blob: f32ce966544d4bb84dcccd04007a59b13db9cc6a [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001//===------------------------- locale.cpp ---------------------------------===//
2//
Howard Hinnantf5256e12010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "string"
11#include "locale"
Howard Hinnant87d1a8a2010-05-30 21:39:41 +000012#include "codecvt"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000013#include "vector"
14#include "algorithm"
15#include "algorithm"
16#include "typeinfo"
17#include "clocale"
18#include "cstring"
19#include "cwctype"
20#include "__sso_allocator"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021#include <langinfo.h>
22#include <stdlib.h>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26namespace {
27
28struct release
29{
30 void operator()(locale::facet* p) {p->__release_shared();}
31};
32
33template <class T, class A0>
34inline
35T&
36make(A0 a0)
37{
38 static typename aligned_storage<sizeof(T)>::type buf;
39 ::new (&buf) T(a0);
40 return *(T*)&buf;
41}
42
43template <class T, class A0, class A1>
44inline
45T&
46make(A0 a0, A1 a1)
47{
48 static typename aligned_storage<sizeof(T)>::type buf;
49 ::new (&buf) T(a0, a1);
50 return *(T*)&buf;
51}
52
53template <class T, class A0, class A1, class A2>
54inline
55T&
56make(A0 a0, A1 a1, A2 a2)
57{
58 static typename aligned_storage<sizeof(T)>::type buf;
59 ::new (&buf) T(a0, a1, a2);
60 return *(T*)&buf;
61}
62
63}
64
65class _LIBCPP_HIDDEN locale::__imp
66 : public facet
67{
68 enum {N = 28};
69 string name_;
70 vector<facet*, __sso_allocator<facet*, N> > facets_;
71public:
72 explicit __imp(size_t refs = 0);
73 explicit __imp(const string& name, size_t refs = 0);
74 __imp(const __imp&);
75 __imp(const __imp&, const string&, locale::category c);
76 __imp(const __imp& other, const __imp& one, locale::category c);
77 __imp(const __imp&, facet* f, long id);
78 ~__imp();
79
80 const string& name() const {return name_;}
81 bool has_facet(long id) const {return id < facets_.size() && facets_[id];}
82 const locale::facet* use_facet(long id) const;
83
84 static const locale& make_classic();
85 static locale& make_global();
86private:
87 void install(facet* f, long id);
88 template <class F> void install(F* f) {install(f, f->id.__get());}
89 template <class F> void install_from(const __imp& other);
90};
91
92locale::__imp::__imp(size_t refs)
93 : facet(refs),
94 name_("C"),
95 facets_(N)
96{
97 facets_.clear();
98 install(&make<_STD::collate<char> >(1));
99 install(&make<_STD::collate<wchar_t> >(1));
100 install(&make<_STD::ctype<char> >((ctype_base::mask*)0, false, 1));
101 install(&make<_STD::ctype<wchar_t> >(1));
102 install(&make<codecvt<char, char, mbstate_t> >(1));
103 install(&make<codecvt<wchar_t, char, mbstate_t> >(1));
104 install(&make<codecvt<char16_t, char, mbstate_t> >(1));
105 install(&make<codecvt<char32_t, char, mbstate_t> >(1));
106 install(&make<numpunct<char> >(1));
107 install(&make<numpunct<wchar_t> >(1));
108 install(&make<num_get<char> >(1));
109 install(&make<num_get<wchar_t> >(1));
110 install(&make<num_put<char> >(1));
111 install(&make<num_put<wchar_t> >(1));
112 install(&make<moneypunct<char, false> >(1));
113 install(&make<moneypunct<char, true> >(1));
114 install(&make<moneypunct<wchar_t, false> >(1));
115 install(&make<moneypunct<wchar_t, true> >(1));
116 install(&make<money_get<char> >(1));
117 install(&make<money_get<wchar_t> >(1));
118 install(&make<money_put<char> >(1));
119 install(&make<money_put<wchar_t> >(1));
120 install(&make<time_get<char> >(1));
121 install(&make<time_get<wchar_t> >(1));
122 install(&make<time_put<char> >(1));
123 install(&make<time_put<wchar_t> >(1));
124 install(&make<_STD::messages<char> >(1));
125 install(&make<_STD::messages<wchar_t> >(1));
126}
127
128locale::__imp::__imp(const string& name, size_t refs)
129 : facet(refs),
130 name_(name),
131 facets_(N)
132{
Howard Hinnantd4444702010-08-11 17:04:31 +0000133#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134 try
135 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000136#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000137 facets_ = locale::classic().__locale_->facets_;
138 for (unsigned i = 0; i < facets_.size(); ++i)
139 if (facets_[i])
140 facets_[i]->__add_shared();
141 install(new collate_byname<char>(name_));
142 install(new collate_byname<wchar_t>(name_));
143 install(new ctype_byname<char>(name_));
144 install(new ctype_byname<wchar_t>(name_));
145 install(new codecvt_byname<char, char, mbstate_t>(name_));
146 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
147 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
148 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
149 install(new numpunct_byname<char>(name_));
150 install(new numpunct_byname<wchar_t>(name_));
151 install(new moneypunct_byname<char, false>(name_));
152 install(new moneypunct_byname<char, true>(name_));
153 install(new moneypunct_byname<wchar_t, false>(name_));
154 install(new moneypunct_byname<wchar_t, true>(name_));
155 install(new time_get_byname<char>(name_));
156 install(new time_get_byname<wchar_t>(name_));
157 install(new time_put_byname<char>(name_));
158 install(new time_put_byname<wchar_t>(name_));
159 install(new messages_byname<char>(name_));
160 install(new messages_byname<wchar_t>(name_));
Howard Hinnantd4444702010-08-11 17:04:31 +0000161#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000162 }
163 catch (...)
164 {
165 for (unsigned i = 0; i < facets_.size(); ++i)
166 if (facets_[i])
167 facets_[i]->__release_shared();
168 throw;
169 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000170#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000171}
172
173locale::__imp::__imp(const __imp& other)
174 : name_(other.name_),
175 facets_(max<size_t>(N, other.facets_.size()))
176{
177 facets_ = other.facets_;
178 for (unsigned i = 0; i < facets_.size(); ++i)
179 if (facets_[i])
180 facets_[i]->__add_shared();
181}
182
183locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
184 : name_("*"),
185 facets_(N)
186{
187 facets_ = other.facets_;
188 for (unsigned i = 0; i < facets_.size(); ++i)
189 if (facets_[i])
190 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000191#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192 try
193 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000194#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195 if (c & locale::collate)
196 {
197 install(new collate_byname<char>(name));
198 install(new collate_byname<wchar_t>(name));
199 }
200 if (c & locale::ctype)
201 {
202 install(new ctype_byname<char>(name));
203 install(new ctype_byname<wchar_t>(name));
204 install(new codecvt_byname<char, char, mbstate_t>(name));
205 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
206 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
207 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
208 }
209 if (c & locale::monetary)
210 {
211 install(new moneypunct_byname<char, false>(name));
212 install(new moneypunct_byname<char, true>(name));
213 install(new moneypunct_byname<wchar_t, false>(name));
214 install(new moneypunct_byname<wchar_t, true>(name));
215 }
216 if (c & locale::numeric)
217 {
218 install(new numpunct_byname<char>(name));
219 install(new numpunct_byname<wchar_t>(name));
220 }
221 if (c & locale::time)
222 {
223 install(new time_get_byname<char>(name));
224 install(new time_get_byname<wchar_t>(name));
225 install(new time_put_byname<char>(name));
226 install(new time_put_byname<wchar_t>(name));
227 }
228 if (c & locale::messages)
229 {
230 install(new messages_byname<char>(name));
231 install(new messages_byname<wchar_t>(name));
232 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000233#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000234 }
235 catch (...)
236 {
237 for (unsigned i = 0; i < facets_.size(); ++i)
238 if (facets_[i])
239 facets_[i]->__release_shared();
240 throw;
241 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000242#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000243}
244
245template<class F>
246inline
247void
248locale::__imp::install_from(const locale::__imp& one)
249{
250 long id = F::id.__get();
251 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
252}
253
254locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
255 : name_("*"),
256 facets_(N)
257{
258 facets_ = other.facets_;
259 for (unsigned i = 0; i < facets_.size(); ++i)
260 if (facets_[i])
261 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000262#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000263 try
264 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000265#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000266 if (c & locale::collate)
267 {
268 install_from<_STD::collate<char> >(one);
269 install_from<_STD::collate<wchar_t> >(one);
270 }
271 if (c & locale::ctype)
272 {
273 install_from<_STD::ctype<char> >(one);
274 install_from<_STD::ctype<wchar_t> >(one);
275 install_from<_STD::codecvt<char, char, mbstate_t> >(one);
276 install_from<_STD::codecvt<char16_t, char, mbstate_t> >(one);
277 install_from<_STD::codecvt<char32_t, char, mbstate_t> >(one);
278 install_from<_STD::codecvt<wchar_t, char, mbstate_t> >(one);
279 }
280 if (c & locale::monetary)
281 {
282 install_from<moneypunct<char, false> >(one);
283 install_from<moneypunct<char, true> >(one);
284 install_from<moneypunct<wchar_t, false> >(one);
285 install_from<moneypunct<wchar_t, true> >(one);
286 install_from<money_get<char> >(one);
287 install_from<money_get<wchar_t> >(one);
288 install_from<money_put<char> >(one);
289 install_from<money_put<wchar_t> >(one);
290 }
291 if (c & locale::numeric)
292 {
293 install_from<numpunct<char> >(one);
294 install_from<numpunct<wchar_t> >(one);
295 install_from<num_get<char> >(one);
296 install_from<num_get<wchar_t> >(one);
297 install_from<num_put<char> >(one);
298 install_from<num_put<wchar_t> >(one);
299 }
300 if (c & locale::time)
301 {
302 install_from<time_get<char> >(one);
303 install_from<time_get<wchar_t> >(one);
304 install_from<time_put<char> >(one);
305 install_from<time_put<wchar_t> >(one);
306 }
307 if (c & locale::messages)
308 {
309 install_from<_STD::messages<char> >(one);
310 install_from<_STD::messages<wchar_t> >(one);
311 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000312#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313 }
314 catch (...)
315 {
316 for (unsigned i = 0; i < facets_.size(); ++i)
317 if (facets_[i])
318 facets_[i]->__release_shared();
319 throw;
320 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000321#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000322}
323
324locale::__imp::__imp(const __imp& other, facet* f, long id)
325 : name_("*"),
326 facets_(max<size_t>(N, other.facets_.size()+1))
327{
328 f->__add_shared();
329 unique_ptr<facet, release> hold(f);
330 facets_ = other.facets_;
331 for (unsigned i = 0; i < other.facets_.size(); ++i)
332 if (facets_[i])
333 facets_[i]->__add_shared();
334 install(hold.get(), id);
335}
336
337locale::__imp::~__imp()
338{
339 for (unsigned i = 0; i < facets_.size(); ++i)
340 if (facets_[i])
341 facets_[i]->__release_shared();
342}
343
344void
345locale::__imp::install(facet* f, long id)
346{
347 f->__add_shared();
348 unique_ptr<facet, release> hold(f);
349 if (id >= facets_.size())
350 facets_.resize(id+1);
351 if (facets_[id])
352 facets_[id]->__release_shared();
353 facets_[id] = hold.release();
354}
355
356const locale::facet*
357locale::__imp::use_facet(long id) const
358{
Howard Hinnantd4444702010-08-11 17:04:31 +0000359#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000360 if (!has_facet(id))
361 throw bad_cast();
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000362#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000363 return facets_[id];
364}
365
366// locale
367
368const locale&
369locale::__imp::make_classic()
370{
371 // only one thread can get in here and it only gets in once
372 static aligned_storage<sizeof(locale)>::type buf;
373 locale* c = (locale*)&buf;
374 c->__locale_ = &make<__imp>(1);
375 return *c;
376}
377
378const locale&
379locale::classic()
380{
381 static const locale& c = __imp::make_classic();
382 return c;
383}
384
385locale&
386locale::__imp::make_global()
387{
388 // only one thread can get in here and it only gets in once
389 static aligned_storage<sizeof(locale)>::type buf;
390 locale* g = (locale*)&buf;
391 ::new (&buf) locale(locale::classic());
392 return *(locale*)&buf;
393}
394
395locale&
396locale::__global()
397{
398 static locale& g = __imp::make_global();
399 return g;
400}
401
Howard Hinnantc9834542011-05-31 15:34:58 +0000402locale::locale() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403 : __locale_(__global().__locale_)
404{
405 __locale_->__add_shared();
406}
407
Howard Hinnantc9834542011-05-31 15:34:58 +0000408locale::locale(const locale& l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 : __locale_(l.__locale_)
410{
411 __locale_->__add_shared();
412}
413
Howard Hinnantc9834542011-05-31 15:34:58 +0000414locale::~locale()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000415{
416 __locale_->__release_shared();
417}
418
419const locale&
Howard Hinnantc9834542011-05-31 15:34:58 +0000420locale::operator=(const locale& other) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000421{
422 other.__locale_->__add_shared();
423 __locale_->__release_shared();
424 __locale_ = other.__locale_;
425 return *this;
426}
427
428locale::locale(const char* name)
Howard Hinnantd4444702010-08-11 17:04:31 +0000429#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000430 : __locale_(name ? new __imp(name)
431 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000432#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000433 : __locale_(new __imp(name))
434#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000435{
436 __locale_->__add_shared();
437}
438
439locale::locale(const string& name)
440 : __locale_(new __imp(name))
441{
442 __locale_->__add_shared();
443}
444
445locale::locale(const locale& other, const char* name, category c)
Howard Hinnantd4444702010-08-11 17:04:31 +0000446#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447 : __locale_(name ? new __imp(*other.__locale_, name, c)
448 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000449#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000450 : __locale_(new __imp(*other.__locale_, name, c))
451#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000452{
453 __locale_->__add_shared();
454}
455
456locale::locale(const locale& other, const string& name, category c)
457 : __locale_(new __imp(*other.__locale_, name, c))
458{
459 __locale_->__add_shared();
460}
461
462locale::locale(const locale& other, const locale& one, category c)
463 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
464{
465 __locale_->__add_shared();
466}
467
468string
469locale::name() const
470{
471 return __locale_->name();
472}
473
474void
475locale::__install_ctor(const locale& other, facet* f, long id)
476{
477 if (f)
478 __locale_ = new __imp(*other.__locale_, f, id);
479 else
480 __locale_ = other.__locale_;
481 __locale_->__add_shared();
482}
483
484locale
485locale::global(const locale& loc)
486{
487 locale& g = __global();
488 locale r = g;
489 g = loc;
490 if (g.name() != "*")
491 setlocale(LC_ALL, g.name().c_str());
492 return r;
493}
494
495bool
496locale::has_facet(id& x) const
497{
498 return __locale_->has_facet(x.__get());
499}
500
501const locale::facet*
502locale::use_facet(id& x) const
503{
504 return __locale_->use_facet(x.__get());
505}
506
507bool
508locale::operator==(const locale& y) const
509{
510 return (__locale_ == y.__locale_)
511 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
512}
513
514// locale::facet
515
516locale::facet::~facet()
517{
518}
519
520void
Howard Hinnant1694d232011-05-28 14:41:13 +0000521locale::facet::__on_zero_shared() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000522{
523 delete this;
524}
525
526// locale::id
527
528int32_t locale::id::__next_id = 0;
529
530namespace
531{
532
533class __fake_bind
534{
535 locale::id* id_;
536 void (locale::id::* pmf_)();
537public:
538 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
539 : id_(id), pmf_(pmf) {}
540
541 void operator()() const
542 {
543 (id_->*pmf_)();
544 }
545};
546
547}
548
549long
550locale::id::__get()
551{
552 call_once(__flag_, __fake_bind(&locale::id::__init, this));
553 return __id_ - 1;
554}
555
556void
557locale::id::__init()
558{
Howard Hinnantadff4892010-05-24 17:49:41 +0000559 __id_ = __sync_add_and_fetch(&__next_id, 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000560}
561
562// template <> class collate_byname<char>
563
564collate_byname<char>::collate_byname(const char* n, size_t refs)
565 : collate<char>(refs),
566 __l(newlocale(LC_ALL_MASK, n, 0))
567{
Howard Hinnantd4444702010-08-11 17:04:31 +0000568#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000569 if (__l == 0)
570 throw runtime_error("collate_byname<char>::collate_byname"
571 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000572#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000573}
574
575collate_byname<char>::collate_byname(const string& name, size_t refs)
576 : collate<char>(refs),
577 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
578{
Howard Hinnantd4444702010-08-11 17:04:31 +0000579#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580 if (__l == 0)
581 throw runtime_error("collate_byname<char>::collate_byname"
582 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000583#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000584}
585
586collate_byname<char>::~collate_byname()
587{
588 freelocale(__l);
589}
590
591int
592collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
593 const char_type* __lo2, const char_type* __hi2) const
594{
595 string_type lhs(__lo1, __hi1);
596 string_type rhs(__lo2, __hi2);
597 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
598 if (r < 0)
599 return -1;
600 if (r > 0)
601 return 1;
602 return r;
603}
604
605collate_byname<char>::string_type
606collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
607{
608 const string_type in(lo, hi);
609 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
610 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
611 return out;
612}
613
614// template <> class collate_byname<wchar_t>
615
616collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
617 : collate<wchar_t>(refs),
618 __l(newlocale(LC_ALL_MASK, n, 0))
619{
Howard Hinnantd4444702010-08-11 17:04:31 +0000620#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000621 if (__l == 0)
622 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
623 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000624#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000625}
626
627collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
628 : collate<wchar_t>(refs),
629 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
630{
Howard Hinnantd4444702010-08-11 17:04:31 +0000631#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000632 if (__l == 0)
633 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
634 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000635#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000636}
637
638collate_byname<wchar_t>::~collate_byname()
639{
640 freelocale(__l);
641}
642
643int
644collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
645 const char_type* __lo2, const char_type* __hi2) const
646{
647 string_type lhs(__lo1, __hi1);
648 string_type rhs(__lo2, __hi2);
649 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
650 if (r < 0)
651 return -1;
652 if (r > 0)
653 return 1;
654 return r;
655}
656
657collate_byname<wchar_t>::string_type
658collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
659{
660 const string_type in(lo, hi);
661 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
662 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
663 return out;
664}
665
666// template <> class ctype<wchar_t>;
667
668locale::id ctype<wchar_t>::id;
669
670ctype<wchar_t>::~ctype()
671{
672}
673
674bool
675ctype<wchar_t>::do_is(mask m, char_type c) const
676{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000677#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000678 return isascii(c) ? _DefaultRuneLocale.__runetype[c] & m : false;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000679#else
680 return false;
681#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000682}
683
684const wchar_t*
685ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
686{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000687#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000688 for (; low != high; ++low, ++vec)
689 *vec = static_cast<mask>(isascii(*low) ? _DefaultRuneLocale.__runetype[*low] : 0);
690 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000691#else
692 return NULL;
693#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000694}
695
696const wchar_t*
697ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
698{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000699#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000700 for (; low != high; ++low)
701 if (isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m))
702 break;
703 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000704#else
705 return NULL;
706#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000707}
708
709const wchar_t*
710ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
711{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000712#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713 for (; low != high; ++low)
714 if (!(isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m)))
715 break;
716 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000717#else
718 return NULL;
719#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000720}
721
722wchar_t
723ctype<wchar_t>::do_toupper(char_type c) const
724{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000725#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000726 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000727#else
728 return 0;
729#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730}
731
732const wchar_t*
733ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
734{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000735#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000736 for (; low != high; ++low)
737 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
738 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000739#else
740 return NULL;
741#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000742}
743
744wchar_t
745ctype<wchar_t>::do_tolower(char_type c) const
746{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000747#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000748 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000749#else
750 return 0;
751#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000752}
753
754const wchar_t*
755ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
756{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000757#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000758 for (; low != high; ++low)
759 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
760 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000761#else
762 return NULL;
763#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764}
765
766wchar_t
767ctype<wchar_t>::do_widen(char c) const
768{
769 return c;
770}
771
772const char*
773ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
774{
775 for (; low != high; ++low, ++dest)
776 *dest = *low;
777 return low;
778}
779
780char
781ctype<wchar_t>::do_narrow(char_type c, char dfault) const
782{
783 if (isascii(c))
784 return static_cast<char>(c);
785 return dfault;
786}
787
788const wchar_t*
789ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
790{
791 for (; low != high; ++low, ++dest)
792 if (isascii(*low))
793 *dest = *low;
794 else
795 *dest = dfault;
796 return low;
797}
798
799// template <> class ctype<char>;
800
801locale::id ctype<char>::id;
802
803ctype<char>::ctype(const mask* tab, bool del, size_t refs)
804 : locale::facet(refs),
805 __tab_(tab),
806 __del_(del)
807{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000808#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000809 if (__tab_ == 0)
810 __tab_ = _DefaultRuneLocale.__runetype;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000811#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000812}
813
814ctype<char>::~ctype()
815{
816 if (__tab_ && __del_)
817 delete [] __tab_;
818}
819
820char
821ctype<char>::do_toupper(char_type c) const
822{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000823#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000824 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000825#else
826 return 0;
827#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000828}
829
830const char*
831ctype<char>::do_toupper(char_type* low, const char_type* high) const
832{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000833#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000834 for (; low != high; ++low)
835 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
836 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000837#else
838 return NULL;
839#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000840}
841
842char
843ctype<char>::do_tolower(char_type c) const
844{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000845#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000846 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000847#else
848 return 0;
849#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850}
851
852const char*
853ctype<char>::do_tolower(char_type* low, const char_type* high) const
854{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000855#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000856 for (; low != high; ++low)
857 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
858 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000859#else
860 return NULL;
861#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000862}
863
864char
865ctype<char>::do_widen(char c) const
866{
867 return c;
868}
869
870const char*
871ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
872{
873 for (; low != high; ++low, ++dest)
874 *dest = *low;
875 return low;
876}
877
878char
879ctype<char>::do_narrow(char_type c, char dfault) const
880{
881 if (isascii(c))
882 return static_cast<char>(c);
883 return dfault;
884}
885
886const char*
887ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
888{
889 for (; low != high; ++low, ++dest)
890 if (isascii(*low))
891 *dest = *low;
892 else
893 *dest = dfault;
894 return low;
895}
896
897const ctype<char>::mask*
Howard Hinnantc9834542011-05-31 15:34:58 +0000898ctype<char>::classic_table() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000899{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000900#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901 return _DefaultRuneLocale.__runetype;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000902#else
903 return NULL;
904#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000905}
906
907// template <> class ctype_byname<char>
908
909ctype_byname<char>::ctype_byname(const char* name, size_t refs)
910 : ctype<char>(0, false, refs),
911 __l(newlocale(LC_ALL_MASK, name, 0))
912{
Howard Hinnantd4444702010-08-11 17:04:31 +0000913#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000914 if (__l == 0)
915 throw runtime_error("ctype_byname<char>::ctype_byname"
916 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000917#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918}
919
920ctype_byname<char>::ctype_byname(const string& name, size_t refs)
921 : ctype<char>(0, false, refs),
922 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
923{
Howard Hinnantd4444702010-08-11 17:04:31 +0000924#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000925 if (__l == 0)
926 throw runtime_error("ctype_byname<char>::ctype_byname"
927 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000928#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000929}
930
931ctype_byname<char>::~ctype_byname()
932{
933 freelocale(__l);
934}
935
936char
937ctype_byname<char>::do_toupper(char_type c) const
938{
939 return toupper_l(c, __l);
940}
941
942const char*
943ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
944{
945 for (; low != high; ++low)
946 *low = toupper_l(*low, __l);
947 return low;
948}
949
950char
951ctype_byname<char>::do_tolower(char_type c) const
952{
953 return tolower_l(c, __l);
954}
955
956const char*
957ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
958{
959 for (; low != high; ++low)
960 *low = tolower_l(*low, __l);
961 return low;
962}
963
964// template <> class ctype_byname<wchar_t>
965
966ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
967 : ctype<wchar_t>(refs),
968 __l(newlocale(LC_ALL_MASK, name, 0))
969{
Howard Hinnantd4444702010-08-11 17:04:31 +0000970#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000971 if (__l == 0)
972 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
973 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000974#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000975}
976
977ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
978 : ctype<wchar_t>(refs),
979 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
980{
Howard Hinnantd4444702010-08-11 17:04:31 +0000981#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000982 if (__l == 0)
983 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
984 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000985#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000986}
987
988ctype_byname<wchar_t>::~ctype_byname()
989{
990 freelocale(__l);
991}
992
993bool
994ctype_byname<wchar_t>::do_is(mask m, char_type c) const
995{
996 return static_cast<bool>(iswctype_l(c, m, __l));
997}
998
999const wchar_t*
1000ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1001{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001002#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001003 for (; low != high; ++low, ++vec)
1004 {
1005 if (isascii(*low))
1006 *vec = static_cast<mask>(_DefaultRuneLocale.__runetype[*low]);
1007 else
1008 {
1009 *vec = 0;
1010 if (iswspace_l(*low, __l))
1011 *vec |= space;
1012 if (iswprint_l(*low, __l))
1013 *vec |= print;
1014 if (iswcntrl_l(*low, __l))
1015 *vec |= cntrl;
1016 if (iswupper_l(*low, __l))
1017 *vec |= upper;
1018 if (iswlower_l(*low, __l))
1019 *vec |= lower;
1020 if (iswalpha_l(*low, __l))
1021 *vec |= alpha;
1022 if (iswdigit_l(*low, __l))
1023 *vec |= digit;
1024 if (iswpunct_l(*low, __l))
1025 *vec |= punct;
1026 if (iswxdigit_l(*low, __l))
1027 *vec |= xdigit;
1028 }
1029 }
1030 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001031#else
1032 return NULL;
1033#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001034}
1035
1036const wchar_t*
1037ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1038{
1039 for (; low != high; ++low)
1040 if (iswctype_l(*low, m, __l))
1041 break;
1042 return low;
1043}
1044
1045const wchar_t*
1046ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1047{
1048 for (; low != high; ++low)
1049 if (!iswctype_l(*low, m, __l))
1050 break;
1051 return low;
1052}
1053
1054wchar_t
1055ctype_byname<wchar_t>::do_toupper(char_type c) const
1056{
1057 return towupper_l(c, __l);
1058}
1059
1060const wchar_t*
1061ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1062{
1063 for (; low != high; ++low)
1064 *low = towupper_l(*low, __l);
1065 return low;
1066}
1067
1068wchar_t
1069ctype_byname<wchar_t>::do_tolower(char_type c) const
1070{
1071 return towlower_l(c, __l);
1072}
1073
1074const wchar_t*
1075ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1076{
1077 for (; low != high; ++low)
1078 *low = towlower_l(*low, __l);
1079 return low;
1080}
1081
1082wchar_t
1083ctype_byname<wchar_t>::do_widen(char c) const
1084{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001085#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001086 return btowc_l(c, __l);
Michael J. Spencer626916f2010-12-10 19:47:54 +00001087#else
1088 return 0;
1089#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001090}
1091
1092const char*
1093ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1094{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001095#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001096 for (; low != high; ++low, ++dest)
1097 *dest = btowc_l(*low, __l);
1098 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001099#else
1100 return NULL;
1101#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001102}
1103
1104char
1105ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1106{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001107#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001108 int r = wctob_l(c, __l);
1109 return r != WEOF ? static_cast<char>(r) : dfault;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001110#else
1111 return 0;
1112#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113}
1114
1115const wchar_t*
1116ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1117{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001118#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001119 for (; low != high; ++low, ++dest)
1120 {
1121 int r = wctob_l(*low, __l);
1122 *dest = r != WEOF ? static_cast<char>(r) : dfault;
1123 }
1124 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001125#else
1126 return NULL;
1127#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001128}
1129
1130// template <> class codecvt<char, char, mbstate_t>
1131
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001132locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001133
1134codecvt<char, char, mbstate_t>::~codecvt()
1135{
1136}
1137
1138codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001139codecvt<char, char, mbstate_t>::do_out(state_type&,
1140 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001141 extern_type* to, extern_type*, extern_type*& to_nxt) const
1142{
1143 frm_nxt = frm;
1144 to_nxt = to;
1145 return noconv;
1146}
1147
1148codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001149codecvt<char, char, mbstate_t>::do_in(state_type&,
1150 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001151 intern_type* to, intern_type*, intern_type*& to_nxt) const
1152{
1153 frm_nxt = frm;
1154 to_nxt = to;
1155 return noconv;
1156}
1157
1158codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001159codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001160 extern_type* to, extern_type*, extern_type*& to_nxt) const
1161{
1162 to_nxt = to;
1163 return noconv;
1164}
1165
1166int
Howard Hinnantc9834542011-05-31 15:34:58 +00001167codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001168{
1169 return 1;
1170}
1171
1172bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001173codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001174{
1175 return true;
1176}
1177
1178int
1179codecvt<char, char, mbstate_t>::do_length(state_type&,
1180 const extern_type* frm, const extern_type* end, size_t mx) const
1181{
1182 return static_cast<int>(min<size_t>(mx, end-frm));
1183}
1184
1185int
Howard Hinnantc9834542011-05-31 15:34:58 +00001186codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001187{
1188 return 1;
1189}
1190
1191// template <> class codecvt<wchar_t, char, mbstate_t>
1192
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001193locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001194
1195codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1196 : locale::facet(refs),
1197 __l(0)
1198{
1199}
1200
1201codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1202 : locale::facet(refs),
1203 __l(newlocale(LC_ALL_MASK, nm, 0))
1204{
Howard Hinnantd4444702010-08-11 17:04:31 +00001205#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001206 if (__l == 0)
1207 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1208 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001209#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001210}
1211
1212codecvt<wchar_t, char, mbstate_t>::~codecvt()
1213{
1214 if (__l != 0)
1215 freelocale(__l);
1216}
1217
1218codecvt<wchar_t, char, mbstate_t>::result
1219codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001220 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001221 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1222{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001223#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001224 // look for first internal null in frm
1225 const intern_type* fend = frm;
1226 for (; fend != frm_end; ++fend)
1227 if (*fend == 0)
1228 break;
1229 // loop over all null-terminated sequences in frm
1230 to_nxt = to;
1231 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1232 {
1233 // save state in case needed to reover to_nxt on error
1234 mbstate_t save_state = st;
1235 size_t n = wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1236 if (n == size_t(-1))
1237 {
1238 // need to recover to_nxt
1239 for (to_nxt = to; frm != frm_nxt; ++frm)
1240 {
1241 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1242 if (n == size_t(-1))
1243 break;
1244 to_nxt += n;
1245 }
1246 frm_nxt = frm;
1247 return error;
1248 }
1249 if (n == 0)
1250 return partial;
1251 to_nxt += n;
1252 if (to_nxt == to_end)
1253 break;
1254 if (fend != frm_end) // set up next null terminated sequence
1255 {
1256 // Try to write the terminating null
1257 extern_type tmp[MB_LEN_MAX];
1258 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1259 if (n == size_t(-1)) // on error
1260 return error;
1261 if (n > to_end-to_nxt) // is there room?
1262 return partial;
1263 for (extern_type* p = tmp; n; --n) // write it
1264 *to_nxt++ = *p++;
1265 ++frm_nxt;
1266 // look for next null in frm
1267 for (fend = frm_nxt; fend != frm_end; ++fend)
1268 if (*fend == 0)
1269 break;
1270 }
1271 }
1272 return frm_nxt == frm_end ? ok : partial;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001273#else
1274 return error;
1275#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001276}
1277
1278codecvt<wchar_t, char, mbstate_t>::result
1279codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001280 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001281 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1282{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001283#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001284 // look for first internal null in frm
1285 const extern_type* fend = frm;
1286 for (; fend != frm_end; ++fend)
1287 if (*fend == 0)
1288 break;
1289 // loop over all null-terminated sequences in frm
1290 to_nxt = to;
1291 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1292 {
1293 // save state in case needed to reover to_nxt on error
1294 mbstate_t save_state = st;
1295 size_t n = mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1296 if (n == size_t(-1))
1297 {
1298 // need to recover to_nxt
1299 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1300 {
1301 n = mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1302 switch (n)
1303 {
1304 case 0:
1305 ++frm;
1306 break;
1307 case -1:
1308 frm_nxt = frm;
1309 return error;
1310 case -2:
1311 frm_nxt = frm;
1312 return partial;
1313 default:
1314 frm += n;
1315 break;
1316 }
1317 }
1318 frm_nxt = frm;
1319 return frm_nxt == frm_end ? ok : partial;
1320 }
1321 if (n == 0)
1322 return error;
1323 to_nxt += n;
1324 if (to_nxt == to_end)
1325 break;
1326 if (fend != frm_end) // set up next null terminated sequence
1327 {
1328 // Try to write the terminating null
1329 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1330 if (n != 0) // on error
1331 return error;
1332 ++to_nxt;
1333 ++frm_nxt;
1334 // look for next null in frm
1335 for (fend = frm_nxt; fend != frm_end; ++fend)
1336 if (*fend == 0)
1337 break;
1338 }
1339 }
1340 return frm_nxt == frm_end ? ok : partial;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001341#else
1342 return error;
1343#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001344}
1345
1346codecvt<wchar_t, char, mbstate_t>::result
1347codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1348 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1349{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001350#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001351 to_nxt = to;
1352 extern_type tmp[MB_LEN_MAX];
1353 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1354 if (n == size_t(-1) || n == 0) // on error
1355 return error;
1356 --n;
1357 if (n > to_end-to_nxt) // is there room?
1358 return partial;
1359 for (extern_type* p = tmp; n; --n) // write it
1360 *to_nxt++ = *p++;
1361 return ok;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001362#else
1363 return error;
1364#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001365}
1366
1367int
Howard Hinnantc9834542011-05-31 15:34:58 +00001368codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001369{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001370#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001371 if (mbtowc_l(0, 0, MB_LEN_MAX, __l) == 0)
1372 {
1373 // stateless encoding
1374 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1375 return 1; // which take more than 1 char to form a wchar_t
1376 return 0;
1377 }
1378 return -1;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001379#else
1380 return 0;
1381#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001382}
1383
1384bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001385codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001386{
1387 return false;
1388}
1389
1390int
1391codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1392 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1393{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001394#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001395 int nbytes = 0;
1396 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1397 {
1398 size_t n = mbrlen_l(frm, frm_end-frm, &st, __l);
1399 switch (n)
1400 {
1401 case 0:
1402 ++nbytes;
1403 ++frm;
1404 break;
1405 case -1:
1406 case -2:
1407 return nbytes;
1408 default:
1409 nbytes += n;
1410 frm += n;
1411 break;
1412 }
1413 }
1414 return nbytes;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001415#else
1416 return 0;
1417#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001418}
1419
1420int
Howard Hinnantc9834542011-05-31 15:34:58 +00001421codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001422{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001423#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001424 return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
Michael J. Spencer626916f2010-12-10 19:47:54 +00001425#else
1426 return 0;
1427#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001428}
1429
1430// Valid UTF ranges
1431// UTF-32 UTF-16 UTF-8 # of code points
1432// first second first second third fourth
1433// 000000 - 00007F 0000 - 007F 00 - 7F 127
1434// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1435// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1436// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1437// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1438// 00D800 - 00DFFF invalid
1439// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1440// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1441// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1442// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1443
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00001444static
1445codecvt_base::result
1446utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1447 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1448 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1449{
1450 frm_nxt = frm;
1451 to_nxt = to;
1452 if (mode & generate_header)
1453 {
1454 if (to_end-to_nxt < 3)
1455 return codecvt_base::partial;
1456 *to_nxt++ = static_cast<uint8_t>(0xEF);
1457 *to_nxt++ = static_cast<uint8_t>(0xBB);
1458 *to_nxt++ = static_cast<uint8_t>(0xBF);
1459 }
1460 for (; frm_nxt < frm_end; ++frm_nxt)
1461 {
1462 uint16_t wc1 = *frm_nxt;
1463 if (wc1 > Maxcode)
1464 return codecvt_base::error;
1465 if (wc1 < 0x0080)
1466 {
1467 if (to_end-to_nxt < 1)
1468 return codecvt_base::partial;
1469 *to_nxt++ = static_cast<uint8_t>(wc1);
1470 }
1471 else if (wc1 < 0x0800)
1472 {
1473 if (to_end-to_nxt < 2)
1474 return codecvt_base::partial;
1475 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1476 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1477 }
1478 else if (wc1 < 0xD800)
1479 {
1480 if (to_end-to_nxt < 3)
1481 return codecvt_base::partial;
1482 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1483 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1484 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1485 }
1486 else if (wc1 < 0xDC00)
1487 {
1488 if (frm_end-frm_nxt < 2)
1489 return codecvt_base::partial;
1490 uint16_t wc2 = frm_nxt[1];
1491 if ((wc2 & 0xFC00) != 0xDC00)
1492 return codecvt_base::error;
1493 if (to_end-to_nxt < 4)
1494 return codecvt_base::partial;
1495 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1496 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1497 return codecvt_base::error;
1498 ++frm_nxt;
1499 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1500 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1501 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1502 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1503 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1504 }
1505 else if (wc1 < 0xE000)
1506 {
1507 return codecvt_base::error;
1508 }
1509 else
1510 {
1511 if (to_end-to_nxt < 3)
1512 return codecvt_base::partial;
1513 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1514 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1515 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1516 }
1517 }
1518 return codecvt_base::ok;
1519}
1520
1521static
1522codecvt_base::result
1523utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1524 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1525 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1526{
1527 frm_nxt = frm;
1528 to_nxt = to;
1529 if (mode & generate_header)
1530 {
1531 if (to_end-to_nxt < 3)
1532 return codecvt_base::partial;
1533 *to_nxt++ = static_cast<uint8_t>(0xEF);
1534 *to_nxt++ = static_cast<uint8_t>(0xBB);
1535 *to_nxt++ = static_cast<uint8_t>(0xBF);
1536 }
1537 for (; frm_nxt < frm_end; ++frm_nxt)
1538 {
1539 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1540 if (wc1 > Maxcode)
1541 return codecvt_base::error;
1542 if (wc1 < 0x0080)
1543 {
1544 if (to_end-to_nxt < 1)
1545 return codecvt_base::partial;
1546 *to_nxt++ = static_cast<uint8_t>(wc1);
1547 }
1548 else if (wc1 < 0x0800)
1549 {
1550 if (to_end-to_nxt < 2)
1551 return codecvt_base::partial;
1552 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1553 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1554 }
1555 else if (wc1 < 0xD800)
1556 {
1557 if (to_end-to_nxt < 3)
1558 return codecvt_base::partial;
1559 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1560 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1561 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1562 }
1563 else if (wc1 < 0xDC00)
1564 {
1565 if (frm_end-frm_nxt < 2)
1566 return codecvt_base::partial;
1567 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1568 if ((wc2 & 0xFC00) != 0xDC00)
1569 return codecvt_base::error;
1570 if (to_end-to_nxt < 4)
1571 return codecvt_base::partial;
1572 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1573 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1574 return codecvt_base::error;
1575 ++frm_nxt;
1576 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1577 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1578 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1579 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1580 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1581 }
1582 else if (wc1 < 0xE000)
1583 {
1584 return codecvt_base::error;
1585 }
1586 else
1587 {
1588 if (to_end-to_nxt < 3)
1589 return codecvt_base::partial;
1590 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1591 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1592 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1593 }
1594 }
1595 return codecvt_base::ok;
1596}
1597
1598static
1599codecvt_base::result
1600utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1601 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1602 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1603{
1604 frm_nxt = frm;
1605 to_nxt = to;
1606 if (mode & consume_header)
1607 {
1608 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1609 frm_nxt[2] == 0xBF)
1610 frm_nxt += 3;
1611 }
1612 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1613 {
1614 uint8_t c1 = *frm_nxt;
1615 if (c1 > Maxcode)
1616 return codecvt_base::error;
1617 if (c1 < 0x80)
1618 {
1619 *to_nxt = static_cast<uint16_t>(c1);
1620 ++frm_nxt;
1621 }
1622 else if (c1 < 0xC2)
1623 {
1624 return codecvt_base::error;
1625 }
1626 else if (c1 < 0xE0)
1627 {
1628 if (frm_end-frm_nxt < 2)
1629 return codecvt_base::partial;
1630 uint8_t c2 = frm_nxt[1];
1631 if ((c2 & 0xC0) != 0x80)
1632 return codecvt_base::error;
1633 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1634 if (t > Maxcode)
1635 return codecvt_base::error;
1636 *to_nxt = t;
1637 frm_nxt += 2;
1638 }
1639 else if (c1 < 0xF0)
1640 {
1641 if (frm_end-frm_nxt < 3)
1642 return codecvt_base::partial;
1643 uint8_t c2 = frm_nxt[1];
1644 uint8_t c3 = frm_nxt[2];
1645 switch (c1)
1646 {
1647 case 0xE0:
1648 if ((c2 & 0xE0) != 0xA0)
1649 return codecvt_base::error;
1650 break;
1651 case 0xED:
1652 if ((c2 & 0xE0) != 0x80)
1653 return codecvt_base::error;
1654 break;
1655 default:
1656 if ((c2 & 0xC0) != 0x80)
1657 return codecvt_base::error;
1658 break;
1659 }
1660 if ((c3 & 0xC0) != 0x80)
1661 return codecvt_base::error;
1662 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1663 | ((c2 & 0x3F) << 6)
1664 | (c3 & 0x3F));
1665 if (t > Maxcode)
1666 return codecvt_base::error;
1667 *to_nxt = t;
1668 frm_nxt += 3;
1669 }
1670 else if (c1 < 0xF5)
1671 {
1672 if (frm_end-frm_nxt < 4)
1673 return codecvt_base::partial;
1674 uint8_t c2 = frm_nxt[1];
1675 uint8_t c3 = frm_nxt[2];
1676 uint8_t c4 = frm_nxt[3];
1677 switch (c1)
1678 {
1679 case 0xF0:
1680 if (!(0x90 <= c2 && c2 <= 0xBF))
1681 return codecvt_base::error;
1682 break;
1683 case 0xF4:
1684 if ((c2 & 0xF0) != 0x80)
1685 return codecvt_base::error;
1686 break;
1687 default:
1688 if ((c2 & 0xC0) != 0x80)
1689 return codecvt_base::error;
1690 break;
1691 }
1692 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1693 return codecvt_base::error;
1694 if (to_end-to_nxt < 2)
1695 return codecvt_base::partial;
1696 if (((((unsigned long)c1 & 7) << 18) +
1697 (((unsigned long)c2 & 0x3F) << 12) +
1698 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1699 return codecvt_base::error;
1700 *to_nxt = static_cast<uint16_t>(
1701 0xD800
1702 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1703 | ((c2 & 0x0F) << 2)
1704 | ((c3 & 0x30) >> 4));
1705 *++to_nxt = static_cast<uint16_t>(
1706 0xDC00
1707 | ((c3 & 0x0F) << 6)
1708 | (c4 & 0x3F));
1709 frm_nxt += 4;
1710 }
1711 else
1712 {
1713 return codecvt_base::error;
1714 }
1715 }
1716 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1717}
1718
1719static
1720codecvt_base::result
1721utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1722 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1723 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1724{
1725 frm_nxt = frm;
1726 to_nxt = to;
1727 if (mode & consume_header)
1728 {
1729 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1730 frm_nxt[2] == 0xBF)
1731 frm_nxt += 3;
1732 }
1733 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1734 {
1735 uint8_t c1 = *frm_nxt;
1736 if (c1 > Maxcode)
1737 return codecvt_base::error;
1738 if (c1 < 0x80)
1739 {
1740 *to_nxt = static_cast<uint32_t>(c1);
1741 ++frm_nxt;
1742 }
1743 else if (c1 < 0xC2)
1744 {
1745 return codecvt_base::error;
1746 }
1747 else if (c1 < 0xE0)
1748 {
1749 if (frm_end-frm_nxt < 2)
1750 return codecvt_base::partial;
1751 uint8_t c2 = frm_nxt[1];
1752 if ((c2 & 0xC0) != 0x80)
1753 return codecvt_base::error;
1754 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1755 if (t > Maxcode)
1756 return codecvt_base::error;
1757 *to_nxt = static_cast<uint32_t>(t);
1758 frm_nxt += 2;
1759 }
1760 else if (c1 < 0xF0)
1761 {
1762 if (frm_end-frm_nxt < 3)
1763 return codecvt_base::partial;
1764 uint8_t c2 = frm_nxt[1];
1765 uint8_t c3 = frm_nxt[2];
1766 switch (c1)
1767 {
1768 case 0xE0:
1769 if ((c2 & 0xE0) != 0xA0)
1770 return codecvt_base::error;
1771 break;
1772 case 0xED:
1773 if ((c2 & 0xE0) != 0x80)
1774 return codecvt_base::error;
1775 break;
1776 default:
1777 if ((c2 & 0xC0) != 0x80)
1778 return codecvt_base::error;
1779 break;
1780 }
1781 if ((c3 & 0xC0) != 0x80)
1782 return codecvt_base::error;
1783 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1784 | ((c2 & 0x3F) << 6)
1785 | (c3 & 0x3F));
1786 if (t > Maxcode)
1787 return codecvt_base::error;
1788 *to_nxt = static_cast<uint32_t>(t);
1789 frm_nxt += 3;
1790 }
1791 else if (c1 < 0xF5)
1792 {
1793 if (frm_end-frm_nxt < 4)
1794 return codecvt_base::partial;
1795 uint8_t c2 = frm_nxt[1];
1796 uint8_t c3 = frm_nxt[2];
1797 uint8_t c4 = frm_nxt[3];
1798 switch (c1)
1799 {
1800 case 0xF0:
1801 if (!(0x90 <= c2 && c2 <= 0xBF))
1802 return codecvt_base::error;
1803 break;
1804 case 0xF4:
1805 if ((c2 & 0xF0) != 0x80)
1806 return codecvt_base::error;
1807 break;
1808 default:
1809 if ((c2 & 0xC0) != 0x80)
1810 return codecvt_base::error;
1811 break;
1812 }
1813 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1814 return codecvt_base::error;
1815 if (to_end-to_nxt < 2)
1816 return codecvt_base::partial;
1817 if (((((unsigned long)c1 & 7) << 18) +
1818 (((unsigned long)c2 & 0x3F) << 12) +
1819 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1820 return codecvt_base::error;
1821 *to_nxt = static_cast<uint32_t>(
1822 0xD800
1823 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1824 | ((c2 & 0x0F) << 2)
1825 | ((c3 & 0x30) >> 4));
1826 *++to_nxt = static_cast<uint32_t>(
1827 0xDC00
1828 | ((c3 & 0x0F) << 6)
1829 | (c4 & 0x3F));
1830 frm_nxt += 4;
1831 }
1832 else
1833 {
1834 return codecvt_base::error;
1835 }
1836 }
1837 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1838}
1839
1840static
1841int
1842utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1843 size_t mx, unsigned long Maxcode = 0x10FFFF,
1844 codecvt_mode mode = codecvt_mode(0))
1845{
1846 const uint8_t* frm_nxt = frm;
1847 if (mode & consume_header)
1848 {
1849 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1850 frm_nxt[2] == 0xBF)
1851 frm_nxt += 3;
1852 }
1853 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1854 {
1855 uint8_t c1 = *frm_nxt;
1856 if (c1 > Maxcode)
1857 break;
1858 if (c1 < 0x80)
1859 {
1860 ++frm_nxt;
1861 }
1862 else if (c1 < 0xC2)
1863 {
1864 break;
1865 }
1866 else if (c1 < 0xE0)
1867 {
1868 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1869 break;
1870 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1871 if (t > Maxcode)
1872 break;
1873 frm_nxt += 2;
1874 }
1875 else if (c1 < 0xF0)
1876 {
1877 if (frm_end-frm_nxt < 3)
1878 break;
1879 uint8_t c2 = frm_nxt[1];
1880 uint8_t c3 = frm_nxt[2];
1881 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1882 | ((c2 & 0x3F) << 6)
1883 | (c3 & 0x3F));
1884 switch (c1)
1885 {
1886 case 0xE0:
1887 if ((c2 & 0xE0) != 0xA0)
1888 return static_cast<int>(frm_nxt - frm);
1889 break;
1890 case 0xED:
1891 if ((c2 & 0xE0) != 0x80)
1892 return static_cast<int>(frm_nxt - frm);
1893 break;
1894 default:
1895 if ((c2 & 0xC0) != 0x80)
1896 return static_cast<int>(frm_nxt - frm);
1897 break;
1898 }
1899 if ((c3 & 0xC0) != 0x80)
1900 break;
1901 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
1902 break;
1903 frm_nxt += 3;
1904 }
1905 else if (c1 < 0xF5)
1906 {
1907 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
1908 break;
1909 uint8_t c2 = frm_nxt[1];
1910 uint8_t c3 = frm_nxt[2];
1911 uint8_t c4 = frm_nxt[3];
1912 switch (c1)
1913 {
1914 case 0xF0:
1915 if (!(0x90 <= c2 && c2 <= 0xBF))
1916 return static_cast<int>(frm_nxt - frm);
1917 break;
1918 case 0xF4:
1919 if ((c2 & 0xF0) != 0x80)
1920 return static_cast<int>(frm_nxt - frm);
1921 break;
1922 default:
1923 if ((c2 & 0xC0) != 0x80)
1924 return static_cast<int>(frm_nxt - frm);
1925 break;
1926 }
1927 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1928 break;
1929 if (((((unsigned long)c1 & 7) << 18) +
1930 (((unsigned long)c2 & 0x3F) << 12) +
1931 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1932 break;
1933 ++nchar16_t;
1934 frm_nxt += 4;
1935 }
1936 else
1937 {
1938 break;
1939 }
1940 }
1941 return static_cast<int>(frm_nxt - frm);
1942}
1943
1944static
1945codecvt_base::result
1946ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1947 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1948 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1949{
1950 frm_nxt = frm;
1951 to_nxt = to;
1952 if (mode & generate_header)
1953 {
1954 if (to_end-to_nxt < 3)
1955 return codecvt_base::partial;
1956 *to_nxt++ = static_cast<uint8_t>(0xEF);
1957 *to_nxt++ = static_cast<uint8_t>(0xBB);
1958 *to_nxt++ = static_cast<uint8_t>(0xBF);
1959 }
1960 for (; frm_nxt < frm_end; ++frm_nxt)
1961 {
1962 uint32_t wc = *frm_nxt;
1963 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
1964 return codecvt_base::error;
1965 if (wc < 0x000080)
1966 {
1967 if (to_end-to_nxt < 1)
1968 return codecvt_base::partial;
1969 *to_nxt++ = static_cast<uint8_t>(wc);
1970 }
1971 else if (wc < 0x000800)
1972 {
1973 if (to_end-to_nxt < 2)
1974 return codecvt_base::partial;
1975 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
1976 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
1977 }
1978 else if (wc < 0x010000)
1979 {
1980 if (to_end-to_nxt < 3)
1981 return codecvt_base::partial;
1982 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
1983 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
1984 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
1985 }
1986 else // if (wc < 0x110000)
1987 {
1988 if (to_end-to_nxt < 4)
1989 return codecvt_base::partial;
1990 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
1991 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
1992 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
1993 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
1994 }
1995 }
1996 return codecvt_base::ok;
1997}
1998
1999static
2000codecvt_base::result
2001utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2002 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2003 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2004{
2005 frm_nxt = frm;
2006 to_nxt = to;
2007 if (mode & consume_header)
2008 {
2009 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2010 frm_nxt[2] == 0xBF)
2011 frm_nxt += 3;
2012 }
2013 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2014 {
2015 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2016 if (c1 < 0x80)
2017 {
2018 if (c1 > Maxcode)
2019 return codecvt_base::error;
2020 *to_nxt = static_cast<uint32_t>(c1);
2021 ++frm_nxt;
2022 }
2023 else if (c1 < 0xC2)
2024 {
2025 return codecvt_base::error;
2026 }
2027 else if (c1 < 0xE0)
2028 {
2029 if (frm_end-frm_nxt < 2)
2030 return codecvt_base::partial;
2031 uint8_t c2 = frm_nxt[1];
2032 if ((c2 & 0xC0) != 0x80)
2033 return codecvt_base::error;
2034 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2035 | (c2 & 0x3F));
2036 if (t > Maxcode)
2037 return codecvt_base::error;
2038 *to_nxt = t;
2039 frm_nxt += 2;
2040 }
2041 else if (c1 < 0xF0)
2042 {
2043 if (frm_end-frm_nxt < 3)
2044 return codecvt_base::partial;
2045 uint8_t c2 = frm_nxt[1];
2046 uint8_t c3 = frm_nxt[2];
2047 switch (c1)
2048 {
2049 case 0xE0:
2050 if ((c2 & 0xE0) != 0xA0)
2051 return codecvt_base::error;
2052 break;
2053 case 0xED:
2054 if ((c2 & 0xE0) != 0x80)
2055 return codecvt_base::error;
2056 break;
2057 default:
2058 if ((c2 & 0xC0) != 0x80)
2059 return codecvt_base::error;
2060 break;
2061 }
2062 if ((c3 & 0xC0) != 0x80)
2063 return codecvt_base::error;
2064 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2065 | ((c2 & 0x3F) << 6)
2066 | (c3 & 0x3F));
2067 if (t > Maxcode)
2068 return codecvt_base::error;
2069 *to_nxt = t;
2070 frm_nxt += 3;
2071 }
2072 else if (c1 < 0xF5)
2073 {
2074 if (frm_end-frm_nxt < 4)
2075 return codecvt_base::partial;
2076 uint8_t c2 = frm_nxt[1];
2077 uint8_t c3 = frm_nxt[2];
2078 uint8_t c4 = frm_nxt[3];
2079 switch (c1)
2080 {
2081 case 0xF0:
2082 if (!(0x90 <= c2 && c2 <= 0xBF))
2083 return codecvt_base::error;
2084 break;
2085 case 0xF4:
2086 if ((c2 & 0xF0) != 0x80)
2087 return codecvt_base::error;
2088 break;
2089 default:
2090 if ((c2 & 0xC0) != 0x80)
2091 return codecvt_base::error;
2092 break;
2093 }
2094 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2095 return codecvt_base::error;
2096 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2097 | ((c2 & 0x3F) << 12)
2098 | ((c3 & 0x3F) << 6)
2099 | (c4 & 0x3F));
2100 if (t > Maxcode)
2101 return codecvt_base::error;
2102 *to_nxt = t;
2103 frm_nxt += 4;
2104 }
2105 else
2106 {
2107 return codecvt_base::error;
2108 }
2109 }
2110 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2111}
2112
2113static
2114int
2115utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2116 size_t mx, unsigned long Maxcode = 0x10FFFF,
2117 codecvt_mode mode = codecvt_mode(0))
2118{
2119 const uint8_t* frm_nxt = frm;
2120 if (mode & consume_header)
2121 {
2122 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2123 frm_nxt[2] == 0xBF)
2124 frm_nxt += 3;
2125 }
2126 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2127 {
2128 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2129 if (c1 < 0x80)
2130 {
2131 if (c1 > Maxcode)
2132 break;
2133 ++frm_nxt;
2134 }
2135 else if (c1 < 0xC2)
2136 {
2137 break;
2138 }
2139 else if (c1 < 0xE0)
2140 {
2141 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2142 break;
2143 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2144 break;
2145 frm_nxt += 2;
2146 }
2147 else if (c1 < 0xF0)
2148 {
2149 if (frm_end-frm_nxt < 3)
2150 break;
2151 uint8_t c2 = frm_nxt[1];
2152 uint8_t c3 = frm_nxt[2];
2153 switch (c1)
2154 {
2155 case 0xE0:
2156 if ((c2 & 0xE0) != 0xA0)
2157 return static_cast<int>(frm_nxt - frm);
2158 break;
2159 case 0xED:
2160 if ((c2 & 0xE0) != 0x80)
2161 return static_cast<int>(frm_nxt - frm);
2162 break;
2163 default:
2164 if ((c2 & 0xC0) != 0x80)
2165 return static_cast<int>(frm_nxt - frm);
2166 break;
2167 }
2168 if ((c3 & 0xC0) != 0x80)
2169 break;
2170 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2171 break;
2172 frm_nxt += 3;
2173 }
2174 else if (c1 < 0xF5)
2175 {
2176 if (frm_end-frm_nxt < 4)
2177 break;
2178 uint8_t c2 = frm_nxt[1];
2179 uint8_t c3 = frm_nxt[2];
2180 uint8_t c4 = frm_nxt[3];
2181 switch (c1)
2182 {
2183 case 0xF0:
2184 if (!(0x90 <= c2 && c2 <= 0xBF))
2185 return static_cast<int>(frm_nxt - frm);
2186 break;
2187 case 0xF4:
2188 if ((c2 & 0xF0) != 0x80)
2189 return static_cast<int>(frm_nxt - frm);
2190 break;
2191 default:
2192 if ((c2 & 0xC0) != 0x80)
2193 return static_cast<int>(frm_nxt - frm);
2194 break;
2195 }
2196 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2197 break;
2198 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2199 | ((c2 & 0x3F) << 12)
2200 | ((c3 & 0x3F) << 6)
2201 | (c4 & 0x3F));
2202 if ((((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
2203 ((c3 & 0x3F) << 6) | (c4 & 0x3F)) > Maxcode)
2204 break;
2205 frm_nxt += 4;
2206 }
2207 else
2208 {
2209 break;
2210 }
2211 }
2212 return static_cast<int>(frm_nxt - frm);
2213}
2214
2215static
2216codecvt_base::result
2217ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2218 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2219 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2220{
2221 frm_nxt = frm;
2222 to_nxt = to;
2223 if (mode & generate_header)
2224 {
2225 if (to_end-to_nxt < 3)
2226 return codecvt_base::partial;
2227 *to_nxt++ = static_cast<uint8_t>(0xEF);
2228 *to_nxt++ = static_cast<uint8_t>(0xBB);
2229 *to_nxt++ = static_cast<uint8_t>(0xBF);
2230 }
2231 for (; frm_nxt < frm_end; ++frm_nxt)
2232 {
2233 uint16_t wc = *frm_nxt;
2234 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2235 return codecvt_base::error;
2236 if (wc < 0x0080)
2237 {
2238 if (to_end-to_nxt < 1)
2239 return codecvt_base::partial;
2240 *to_nxt++ = static_cast<uint8_t>(wc);
2241 }
2242 else if (wc < 0x0800)
2243 {
2244 if (to_end-to_nxt < 2)
2245 return codecvt_base::partial;
2246 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2247 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2248 }
2249 else // if (wc <= 0xFFFF)
2250 {
2251 if (to_end-to_nxt < 3)
2252 return codecvt_base::partial;
2253 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2254 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2255 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2256 }
2257 }
2258 return codecvt_base::ok;
2259}
2260
2261static
2262codecvt_base::result
2263utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2264 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2265 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2266{
2267 frm_nxt = frm;
2268 to_nxt = to;
2269 if (mode & consume_header)
2270 {
2271 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2272 frm_nxt[2] == 0xBF)
2273 frm_nxt += 3;
2274 }
2275 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2276 {
2277 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2278 if (c1 < 0x80)
2279 {
2280 if (c1 > Maxcode)
2281 return codecvt_base::error;
2282 *to_nxt = static_cast<uint16_t>(c1);
2283 ++frm_nxt;
2284 }
2285 else if (c1 < 0xC2)
2286 {
2287 return codecvt_base::error;
2288 }
2289 else if (c1 < 0xE0)
2290 {
2291 if (frm_end-frm_nxt < 2)
2292 return codecvt_base::partial;
2293 uint8_t c2 = frm_nxt[1];
2294 if ((c2 & 0xC0) != 0x80)
2295 return codecvt_base::error;
2296 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2297 | (c2 & 0x3F));
2298 if (t > Maxcode)
2299 return codecvt_base::error;
2300 *to_nxt = t;
2301 frm_nxt += 2;
2302 }
2303 else if (c1 < 0xF0)
2304 {
2305 if (frm_end-frm_nxt < 3)
2306 return codecvt_base::partial;
2307 uint8_t c2 = frm_nxt[1];
2308 uint8_t c3 = frm_nxt[2];
2309 switch (c1)
2310 {
2311 case 0xE0:
2312 if ((c2 & 0xE0) != 0xA0)
2313 return codecvt_base::error;
2314 break;
2315 case 0xED:
2316 if ((c2 & 0xE0) != 0x80)
2317 return codecvt_base::error;
2318 break;
2319 default:
2320 if ((c2 & 0xC0) != 0x80)
2321 return codecvt_base::error;
2322 break;
2323 }
2324 if ((c3 & 0xC0) != 0x80)
2325 return codecvt_base::error;
2326 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2327 | ((c2 & 0x3F) << 6)
2328 | (c3 & 0x3F));
2329 if (t > Maxcode)
2330 return codecvt_base::error;
2331 *to_nxt = t;
2332 frm_nxt += 3;
2333 }
2334 else
2335 {
2336 return codecvt_base::error;
2337 }
2338 }
2339 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2340}
2341
2342static
2343int
2344utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2345 size_t mx, unsigned long Maxcode = 0x10FFFF,
2346 codecvt_mode mode = codecvt_mode(0))
2347{
2348 const uint8_t* frm_nxt = frm;
2349 if (mode & consume_header)
2350 {
2351 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2352 frm_nxt[2] == 0xBF)
2353 frm_nxt += 3;
2354 }
2355 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2356 {
2357 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2358 if (c1 < 0x80)
2359 {
2360 if (c1 > Maxcode)
2361 break;
2362 ++frm_nxt;
2363 }
2364 else if (c1 < 0xC2)
2365 {
2366 break;
2367 }
2368 else if (c1 < 0xE0)
2369 {
2370 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2371 break;
2372 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2373 break;
2374 frm_nxt += 2;
2375 }
2376 else if (c1 < 0xF0)
2377 {
2378 if (frm_end-frm_nxt < 3)
2379 break;
2380 uint8_t c2 = frm_nxt[1];
2381 uint8_t c3 = frm_nxt[2];
2382 switch (c1)
2383 {
2384 case 0xE0:
2385 if ((c2 & 0xE0) != 0xA0)
2386 return static_cast<int>(frm_nxt - frm);
2387 break;
2388 case 0xED:
2389 if ((c2 & 0xE0) != 0x80)
2390 return static_cast<int>(frm_nxt - frm);
2391 break;
2392 default:
2393 if ((c2 & 0xC0) != 0x80)
2394 return static_cast<int>(frm_nxt - frm);
2395 break;
2396 }
2397 if ((c3 & 0xC0) != 0x80)
2398 break;
2399 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2400 break;
2401 frm_nxt += 3;
2402 }
2403 else
2404 {
2405 break;
2406 }
2407 }
2408 return static_cast<int>(frm_nxt - frm);
2409}
2410
2411static
2412codecvt_base::result
2413ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2414 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2415 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2416{
2417 frm_nxt = frm;
2418 to_nxt = to;
2419 if (mode & generate_header)
2420 {
2421 if (to_end-to_nxt < 2)
2422 return codecvt_base::partial;
2423 *to_nxt++ = static_cast<uint8_t>(0xFE);
2424 *to_nxt++ = static_cast<uint8_t>(0xFF);
2425 }
2426 for (; frm_nxt < frm_end; ++frm_nxt)
2427 {
2428 uint32_t wc = *frm_nxt;
2429 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2430 return codecvt_base::error;
2431 if (wc < 0x010000)
2432 {
2433 if (to_end-to_nxt < 2)
2434 return codecvt_base::partial;
2435 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2436 *to_nxt++ = static_cast<uint8_t>(wc);
2437 }
2438 else
2439 {
2440 if (to_end-to_nxt < 4)
2441 return codecvt_base::partial;
2442 uint16_t t = static_cast<uint16_t>(
2443 0xD800
2444 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2445 | ((wc & 0x00FC00) >> 10));
2446 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2447 *to_nxt++ = static_cast<uint8_t>(t);
2448 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2449 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2450 *to_nxt++ = static_cast<uint8_t>(t);
2451 }
2452 }
2453 return codecvt_base::ok;
2454}
2455
2456static
2457codecvt_base::result
2458utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2459 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2460 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2461{
2462 frm_nxt = frm;
2463 to_nxt = to;
2464 if (mode & consume_header)
2465 {
2466 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2467 frm_nxt += 2;
2468 }
2469 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2470 {
2471 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2472 if ((c1 & 0xFC00) == 0xDC00)
2473 return codecvt_base::error;
2474 if ((c1 & 0xFC00) != 0xD800)
2475 {
2476 if (c1 > Maxcode)
2477 return codecvt_base::error;
2478 *to_nxt = static_cast<uint32_t>(c1);
2479 frm_nxt += 2;
2480 }
2481 else
2482 {
2483 if (frm_end-frm_nxt < 4)
2484 return codecvt_base::partial;
2485 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2486 if ((c2 & 0xFC00) != 0xDC00)
2487 return codecvt_base::error;
2488 uint32_t t = static_cast<uint32_t>(
2489 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2490 | ((c1 & 0x003F) << 10)
2491 | (c2 & 0x03FF));
2492 if (t > Maxcode)
2493 return codecvt_base::error;
2494 *to_nxt = t;
2495 frm_nxt += 4;
2496 }
2497 }
2498 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2499}
2500
2501static
2502int
2503utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2504 size_t mx, unsigned long Maxcode = 0x10FFFF,
2505 codecvt_mode mode = codecvt_mode(0))
2506{
2507 const uint8_t* frm_nxt = frm;
2508 frm_nxt = frm;
2509 if (mode & consume_header)
2510 {
2511 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2512 frm_nxt += 2;
2513 }
2514 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2515 {
2516 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2517 if ((c1 & 0xFC00) == 0xDC00)
2518 break;
2519 if ((c1 & 0xFC00) != 0xD800)
2520 {
2521 if (c1 > Maxcode)
2522 break;
2523 frm_nxt += 2;
2524 }
2525 else
2526 {
2527 if (frm_end-frm_nxt < 4)
2528 break;
2529 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2530 if ((c2 & 0xFC00) != 0xDC00)
2531 break;
2532 uint32_t t = static_cast<uint32_t>(
2533 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2534 | ((c1 & 0x003F) << 10)
2535 | (c2 & 0x03FF));
2536 if (t > Maxcode)
2537 break;
2538 frm_nxt += 4;
2539 }
2540 }
2541 return static_cast<int>(frm_nxt - frm);
2542}
2543
2544static
2545codecvt_base::result
2546ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2547 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2548 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2549{
2550 frm_nxt = frm;
2551 to_nxt = to;
2552 if (mode & generate_header)
2553 {
2554 if (to_end-to_nxt < 2)
2555 return codecvt_base::partial;
2556 *to_nxt++ = static_cast<uint8_t>(0xFF);
2557 *to_nxt++ = static_cast<uint8_t>(0xFE);
2558 }
2559 for (; frm_nxt < frm_end; ++frm_nxt)
2560 {
2561 uint32_t wc = *frm_nxt;
2562 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2563 return codecvt_base::error;
2564 if (wc < 0x010000)
2565 {
2566 if (to_end-to_nxt < 2)
2567 return codecvt_base::partial;
2568 *to_nxt++ = static_cast<uint8_t>(wc);
2569 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2570 }
2571 else
2572 {
2573 if (to_end-to_nxt < 4)
2574 return codecvt_base::partial;
2575 uint16_t t = static_cast<uint16_t>(
2576 0xD800
2577 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2578 | ((wc & 0x00FC00) >> 10));
2579 *to_nxt++ = static_cast<uint8_t>(t);
2580 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2581 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2582 *to_nxt++ = static_cast<uint8_t>(t);
2583 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2584 }
2585 }
2586 return codecvt_base::ok;
2587}
2588
2589static
2590codecvt_base::result
2591utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2592 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2593 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2594{
2595 frm_nxt = frm;
2596 to_nxt = to;
2597 if (mode & consume_header)
2598 {
2599 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2600 frm_nxt += 2;
2601 }
2602 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2603 {
2604 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2605 if ((c1 & 0xFC00) == 0xDC00)
2606 return codecvt_base::error;
2607 if ((c1 & 0xFC00) != 0xD800)
2608 {
2609 if (c1 > Maxcode)
2610 return codecvt_base::error;
2611 *to_nxt = static_cast<uint32_t>(c1);
2612 frm_nxt += 2;
2613 }
2614 else
2615 {
2616 if (frm_end-frm_nxt < 4)
2617 return codecvt_base::partial;
2618 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2619 if ((c2 & 0xFC00) != 0xDC00)
2620 return codecvt_base::error;
2621 uint32_t t = static_cast<uint32_t>(
2622 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2623 | ((c1 & 0x003F) << 10)
2624 | (c2 & 0x03FF));
2625 if (t > Maxcode)
2626 return codecvt_base::error;
2627 *to_nxt = t;
2628 frm_nxt += 4;
2629 }
2630 }
2631 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2632}
2633
2634static
2635int
2636utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2637 size_t mx, unsigned long Maxcode = 0x10FFFF,
2638 codecvt_mode mode = codecvt_mode(0))
2639{
2640 const uint8_t* frm_nxt = frm;
2641 frm_nxt = frm;
2642 if (mode & consume_header)
2643 {
2644 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2645 frm_nxt += 2;
2646 }
2647 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2648 {
2649 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2650 if ((c1 & 0xFC00) == 0xDC00)
2651 break;
2652 if ((c1 & 0xFC00) != 0xD800)
2653 {
2654 if (c1 > Maxcode)
2655 break;
2656 frm_nxt += 2;
2657 }
2658 else
2659 {
2660 if (frm_end-frm_nxt < 4)
2661 break;
2662 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2663 if ((c2 & 0xFC00) != 0xDC00)
2664 break;
2665 uint32_t t = static_cast<uint32_t>(
2666 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2667 | ((c1 & 0x003F) << 10)
2668 | (c2 & 0x03FF));
2669 if (t > Maxcode)
2670 break;
2671 frm_nxt += 4;
2672 }
2673 }
2674 return static_cast<int>(frm_nxt - frm);
2675}
2676
2677static
2678codecvt_base::result
2679ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2680 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2681 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2682{
2683 frm_nxt = frm;
2684 to_nxt = to;
2685 if (mode & generate_header)
2686 {
2687 if (to_end-to_nxt < 2)
2688 return codecvt_base::partial;
2689 *to_nxt++ = static_cast<uint8_t>(0xFE);
2690 *to_nxt++ = static_cast<uint8_t>(0xFF);
2691 }
2692 for (; frm_nxt < frm_end; ++frm_nxt)
2693 {
2694 uint16_t wc = *frm_nxt;
2695 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2696 return codecvt_base::error;
2697 if (to_end-to_nxt < 2)
2698 return codecvt_base::partial;
2699 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2700 *to_nxt++ = static_cast<uint8_t>(wc);
2701 }
2702 return codecvt_base::ok;
2703}
2704
2705static
2706codecvt_base::result
2707utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2708 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2709 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2710{
2711 frm_nxt = frm;
2712 to_nxt = to;
2713 if (mode & consume_header)
2714 {
2715 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2716 frm_nxt += 2;
2717 }
2718 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2719 {
2720 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2721 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2722 return codecvt_base::error;
2723 *to_nxt = c1;
2724 frm_nxt += 2;
2725 }
2726 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2727}
2728
2729static
2730int
2731utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2732 size_t mx, unsigned long Maxcode = 0x10FFFF,
2733 codecvt_mode mode = codecvt_mode(0))
2734{
2735 const uint8_t* frm_nxt = frm;
2736 frm_nxt = frm;
2737 if (mode & consume_header)
2738 {
2739 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2740 frm_nxt += 2;
2741 }
2742 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2743 {
2744 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2745 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2746 break;
2747 frm_nxt += 2;
2748 }
2749 return static_cast<int>(frm_nxt - frm);
2750}
2751
2752static
2753codecvt_base::result
2754ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2755 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2756 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2757{
2758 frm_nxt = frm;
2759 to_nxt = to;
2760 if (mode & generate_header)
2761 {
2762 if (to_end-to_nxt < 2)
2763 return codecvt_base::partial;
2764 *to_nxt++ = static_cast<uint8_t>(0xFF);
2765 *to_nxt++ = static_cast<uint8_t>(0xFE);
2766 }
2767 for (; frm_nxt < frm_end; ++frm_nxt)
2768 {
2769 uint16_t wc = *frm_nxt;
2770 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2771 return codecvt_base::error;
2772 if (to_end-to_nxt < 2)
2773 return codecvt_base::partial;
2774 *to_nxt++ = static_cast<uint8_t>(wc);
2775 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2776 }
2777 return codecvt_base::ok;
2778}
2779
2780static
2781codecvt_base::result
2782utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2783 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2784 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2785{
2786 frm_nxt = frm;
2787 to_nxt = to;
2788 if (mode & consume_header)
2789 {
2790 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2791 frm_nxt += 2;
2792 }
2793 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2794 {
2795 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2796 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2797 return codecvt_base::error;
2798 *to_nxt = c1;
2799 frm_nxt += 2;
2800 }
2801 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2802}
2803
2804static
2805int
2806utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2807 size_t mx, unsigned long Maxcode = 0x10FFFF,
2808 codecvt_mode mode = codecvt_mode(0))
2809{
2810 const uint8_t* frm_nxt = frm;
2811 frm_nxt = frm;
2812 if (mode & consume_header)
2813 {
2814 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2815 frm_nxt += 2;
2816 }
2817 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2818 {
2819 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2820 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2821 break;
2822 frm_nxt += 2;
2823 }
2824 return static_cast<int>(frm_nxt - frm);
2825}
2826
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002827// template <> class codecvt<char16_t, char, mbstate_t>
2828
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002829locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002830
2831codecvt<char16_t, char, mbstate_t>::~codecvt()
2832{
2833}
2834
2835codecvt<char16_t, char, mbstate_t>::result
2836codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002837 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002838 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2839{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002840 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2841 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2842 const uint16_t* _frm_nxt = _frm;
2843 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2844 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2845 uint8_t* _to_nxt = _to;
2846 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2847 frm_nxt = frm + (_frm_nxt - _frm);
2848 to_nxt = to + (_to_nxt - _to);
2849 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002850}
2851
2852codecvt<char16_t, char, mbstate_t>::result
2853codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002854 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002855 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2856{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002857 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2858 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2859 const uint8_t* _frm_nxt = _frm;
2860 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2861 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2862 uint16_t* _to_nxt = _to;
2863 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2864 frm_nxt = frm + (_frm_nxt - _frm);
2865 to_nxt = to + (_to_nxt - _to);
2866 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002867}
2868
2869codecvt<char16_t, char, mbstate_t>::result
2870codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2871 extern_type* to, extern_type*, extern_type*& to_nxt) const
2872{
2873 to_nxt = to;
2874 return noconv;
2875}
2876
2877int
Howard Hinnantc9834542011-05-31 15:34:58 +00002878codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002879{
2880 return 0;
2881}
2882
2883bool
Howard Hinnantc9834542011-05-31 15:34:58 +00002884codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002885{
2886 return false;
2887}
2888
2889int
2890codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2891 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2892{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002893 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2894 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2895 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002896}
2897
2898int
Howard Hinnantc9834542011-05-31 15:34:58 +00002899codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002900{
2901 return 4;
2902}
2903
2904// template <> class codecvt<char32_t, char, mbstate_t>
2905
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002906locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002907
2908codecvt<char32_t, char, mbstate_t>::~codecvt()
2909{
2910}
2911
2912codecvt<char32_t, char, mbstate_t>::result
2913codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002914 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002915 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2916{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002917 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
2918 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
2919 const uint32_t* _frm_nxt = _frm;
2920 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2921 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2922 uint8_t* _to_nxt = _to;
2923 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2924 frm_nxt = frm + (_frm_nxt - _frm);
2925 to_nxt = to + (_to_nxt - _to);
2926 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002927}
2928
2929codecvt<char32_t, char, mbstate_t>::result
2930codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002931 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002932 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2933{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002934 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2935 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2936 const uint8_t* _frm_nxt = _frm;
2937 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
2938 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
2939 uint32_t* _to_nxt = _to;
2940 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2941 frm_nxt = frm + (_frm_nxt - _frm);
2942 to_nxt = to + (_to_nxt - _to);
2943 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002944}
2945
2946codecvt<char32_t, char, mbstate_t>::result
2947codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
2948 extern_type* to, extern_type*, extern_type*& to_nxt) const
2949{
2950 to_nxt = to;
2951 return noconv;
2952}
2953
2954int
Howard Hinnantc9834542011-05-31 15:34:58 +00002955codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002956{
2957 return 0;
2958}
2959
2960bool
Howard Hinnantc9834542011-05-31 15:34:58 +00002961codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002962{
2963 return false;
2964}
2965
2966int
2967codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
2968 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2969{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002970 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2971 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2972 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002973}
2974
2975int
Howard Hinnantc9834542011-05-31 15:34:58 +00002976codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002977{
2978 return 4;
2979}
2980
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002981// __codecvt_utf8<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002982
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002983__codecvt_utf8<wchar_t>::result
2984__codecvt_utf8<wchar_t>::do_out(state_type&,
2985 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002986 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2987{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002988 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
2989 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
2990 const uint32_t* _frm_nxt = _frm;
2991 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2992 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2993 uint8_t* _to_nxt = _to;
2994 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
2995 _Maxcode_, _Mode_);
2996 frm_nxt = frm + (_frm_nxt - _frm);
2997 to_nxt = to + (_to_nxt - _to);
2998 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002999}
3000
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003001__codecvt_utf8<wchar_t>::result
3002__codecvt_utf8<wchar_t>::do_in(state_type&,
3003 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003004 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3005{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003006 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3007 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3008 const uint8_t* _frm_nxt = _frm;
3009 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3010 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3011 uint32_t* _to_nxt = _to;
3012 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3013 _Maxcode_, _Mode_);
3014 frm_nxt = frm + (_frm_nxt - _frm);
3015 to_nxt = to + (_to_nxt - _to);
3016 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003017}
3018
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003019__codecvt_utf8<wchar_t>::result
3020__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003021 extern_type* to, extern_type*, extern_type*& to_nxt) const
3022{
3023 to_nxt = to;
3024 return noconv;
3025}
3026
3027int
Howard Hinnantc9834542011-05-31 15:34:58 +00003028__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003029{
3030 return 0;
3031}
3032
3033bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003034__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003035{
3036 return false;
3037}
3038
3039int
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003040__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003041 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3042{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003043 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3044 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3045 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003046}
3047
3048int
Howard Hinnantc9834542011-05-31 15:34:58 +00003049__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003050{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003051 if (_Mode_ & consume_header)
3052 return 7;
3053 return 4;
3054}
3055
3056// __codecvt_utf8<char16_t>
3057
3058__codecvt_utf8<char16_t>::result
3059__codecvt_utf8<char16_t>::do_out(state_type&,
3060 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3061 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3062{
3063 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3064 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3065 const uint16_t* _frm_nxt = _frm;
3066 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3067 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3068 uint8_t* _to_nxt = _to;
3069 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3070 _Maxcode_, _Mode_);
3071 frm_nxt = frm + (_frm_nxt - _frm);
3072 to_nxt = to + (_to_nxt - _to);
3073 return r;
3074}
3075
3076__codecvt_utf8<char16_t>::result
3077__codecvt_utf8<char16_t>::do_in(state_type&,
3078 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3079 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3080{
3081 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3082 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3083 const uint8_t* _frm_nxt = _frm;
3084 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3085 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3086 uint16_t* _to_nxt = _to;
3087 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3088 _Maxcode_, _Mode_);
3089 frm_nxt = frm + (_frm_nxt - _frm);
3090 to_nxt = to + (_to_nxt - _to);
3091 return r;
3092}
3093
3094__codecvt_utf8<char16_t>::result
3095__codecvt_utf8<char16_t>::do_unshift(state_type&,
3096 extern_type* to, extern_type*, extern_type*& to_nxt) const
3097{
3098 to_nxt = to;
3099 return noconv;
3100}
3101
3102int
Howard Hinnantc9834542011-05-31 15:34:58 +00003103__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003104{
3105 return 0;
3106}
3107
3108bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003109__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003110{
3111 return false;
3112}
3113
3114int
3115__codecvt_utf8<char16_t>::do_length(state_type&,
3116 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3117{
3118 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3119 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3120 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3121}
3122
3123int
Howard Hinnantc9834542011-05-31 15:34:58 +00003124__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003125{
3126 if (_Mode_ & consume_header)
3127 return 6;
3128 return 3;
3129}
3130
3131// __codecvt_utf8<char32_t>
3132
3133__codecvt_utf8<char32_t>::result
3134__codecvt_utf8<char32_t>::do_out(state_type&,
3135 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3136 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3137{
3138 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3139 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3140 const uint32_t* _frm_nxt = _frm;
3141 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3142 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3143 uint8_t* _to_nxt = _to;
3144 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3145 _Maxcode_, _Mode_);
3146 frm_nxt = frm + (_frm_nxt - _frm);
3147 to_nxt = to + (_to_nxt - _to);
3148 return r;
3149}
3150
3151__codecvt_utf8<char32_t>::result
3152__codecvt_utf8<char32_t>::do_in(state_type&,
3153 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3154 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3155{
3156 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3157 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3158 const uint8_t* _frm_nxt = _frm;
3159 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3160 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3161 uint32_t* _to_nxt = _to;
3162 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3163 _Maxcode_, _Mode_);
3164 frm_nxt = frm + (_frm_nxt - _frm);
3165 to_nxt = to + (_to_nxt - _to);
3166 return r;
3167}
3168
3169__codecvt_utf8<char32_t>::result
3170__codecvt_utf8<char32_t>::do_unshift(state_type&,
3171 extern_type* to, extern_type*, extern_type*& to_nxt) const
3172{
3173 to_nxt = to;
3174 return noconv;
3175}
3176
3177int
Howard Hinnantc9834542011-05-31 15:34:58 +00003178__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003179{
3180 return 0;
3181}
3182
3183bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003184__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003185{
3186 return false;
3187}
3188
3189int
3190__codecvt_utf8<char32_t>::do_length(state_type&,
3191 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3192{
3193 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3194 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3195 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3196}
3197
3198int
Howard Hinnantc9834542011-05-31 15:34:58 +00003199__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003200{
3201 if (_Mode_ & consume_header)
3202 return 7;
3203 return 4;
3204}
3205
3206// __codecvt_utf16<wchar_t, false>
3207
3208__codecvt_utf16<wchar_t, false>::result
3209__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3210 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3211 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3212{
3213 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3214 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3215 const uint32_t* _frm_nxt = _frm;
3216 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3217 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3218 uint8_t* _to_nxt = _to;
3219 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3220 _Maxcode_, _Mode_);
3221 frm_nxt = frm + (_frm_nxt - _frm);
3222 to_nxt = to + (_to_nxt - _to);
3223 return r;
3224}
3225
3226__codecvt_utf16<wchar_t, false>::result
3227__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3228 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3229 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3230{
3231 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3232 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3233 const uint8_t* _frm_nxt = _frm;
3234 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3235 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3236 uint32_t* _to_nxt = _to;
3237 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3238 _Maxcode_, _Mode_);
3239 frm_nxt = frm + (_frm_nxt - _frm);
3240 to_nxt = to + (_to_nxt - _to);
3241 return r;
3242}
3243
3244__codecvt_utf16<wchar_t, false>::result
3245__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3246 extern_type* to, extern_type*, extern_type*& to_nxt) const
3247{
3248 to_nxt = to;
3249 return noconv;
3250}
3251
3252int
Howard Hinnantc9834542011-05-31 15:34:58 +00003253__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003254{
3255 return 0;
3256}
3257
3258bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003259__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003260{
3261 return false;
3262}
3263
3264int
3265__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3266 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3267{
3268 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3269 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3270 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3271}
3272
3273int
Howard Hinnantc9834542011-05-31 15:34:58 +00003274__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003275{
3276 if (_Mode_ & consume_header)
3277 return 6;
3278 return 4;
3279}
3280
3281// __codecvt_utf16<wchar_t, true>
3282
3283__codecvt_utf16<wchar_t, true>::result
3284__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3285 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3286 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3287{
3288 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3289 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3290 const uint32_t* _frm_nxt = _frm;
3291 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3292 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3293 uint8_t* _to_nxt = _to;
3294 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3295 _Maxcode_, _Mode_);
3296 frm_nxt = frm + (_frm_nxt - _frm);
3297 to_nxt = to + (_to_nxt - _to);
3298 return r;
3299}
3300
3301__codecvt_utf16<wchar_t, true>::result
3302__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3303 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3304 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3305{
3306 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3307 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3308 const uint8_t* _frm_nxt = _frm;
3309 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3310 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3311 uint32_t* _to_nxt = _to;
3312 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3313 _Maxcode_, _Mode_);
3314 frm_nxt = frm + (_frm_nxt - _frm);
3315 to_nxt = to + (_to_nxt - _to);
3316 return r;
3317}
3318
3319__codecvt_utf16<wchar_t, true>::result
3320__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3321 extern_type* to, extern_type*, extern_type*& to_nxt) const
3322{
3323 to_nxt = to;
3324 return noconv;
3325}
3326
3327int
Howard Hinnantc9834542011-05-31 15:34:58 +00003328__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003329{
3330 return 0;
3331}
3332
3333bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003334__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003335{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003336 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003337}
3338
3339int
3340__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3341 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3342{
3343 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3344 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3345 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3346}
3347
3348int
Howard Hinnantc9834542011-05-31 15:34:58 +00003349__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003350{
3351 if (_Mode_ & consume_header)
3352 return 6;
3353 return 4;
3354}
3355
3356// __codecvt_utf16<char16_t, false>
3357
3358__codecvt_utf16<char16_t, false>::result
3359__codecvt_utf16<char16_t, false>::do_out(state_type&,
3360 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3361 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3362{
3363 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3364 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3365 const uint16_t* _frm_nxt = _frm;
3366 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3367 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3368 uint8_t* _to_nxt = _to;
3369 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3370 _Maxcode_, _Mode_);
3371 frm_nxt = frm + (_frm_nxt - _frm);
3372 to_nxt = to + (_to_nxt - _to);
3373 return r;
3374}
3375
3376__codecvt_utf16<char16_t, false>::result
3377__codecvt_utf16<char16_t, false>::do_in(state_type&,
3378 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3379 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3380{
3381 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3382 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3383 const uint8_t* _frm_nxt = _frm;
3384 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3385 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3386 uint16_t* _to_nxt = _to;
3387 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3388 _Maxcode_, _Mode_);
3389 frm_nxt = frm + (_frm_nxt - _frm);
3390 to_nxt = to + (_to_nxt - _to);
3391 return r;
3392}
3393
3394__codecvt_utf16<char16_t, false>::result
3395__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3396 extern_type* to, extern_type*, extern_type*& to_nxt) const
3397{
3398 to_nxt = to;
3399 return noconv;
3400}
3401
3402int
Howard Hinnantc9834542011-05-31 15:34:58 +00003403__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003404{
3405 return 0;
3406}
3407
3408bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003409__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003410{
3411 return false;
3412}
3413
3414int
3415__codecvt_utf16<char16_t, false>::do_length(state_type&,
3416 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3417{
3418 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3419 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3420 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3421}
3422
3423int
Howard Hinnantc9834542011-05-31 15:34:58 +00003424__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003425{
3426 if (_Mode_ & consume_header)
3427 return 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003428 return 2;
3429}
3430
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003431// __codecvt_utf16<char16_t, true>
3432
3433__codecvt_utf16<char16_t, true>::result
3434__codecvt_utf16<char16_t, true>::do_out(state_type&,
3435 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3436 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3437{
3438 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3439 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3440 const uint16_t* _frm_nxt = _frm;
3441 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3442 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3443 uint8_t* _to_nxt = _to;
3444 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3445 _Maxcode_, _Mode_);
3446 frm_nxt = frm + (_frm_nxt - _frm);
3447 to_nxt = to + (_to_nxt - _to);
3448 return r;
3449}
3450
3451__codecvt_utf16<char16_t, true>::result
3452__codecvt_utf16<char16_t, true>::do_in(state_type&,
3453 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3454 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3455{
3456 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3457 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3458 const uint8_t* _frm_nxt = _frm;
3459 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3460 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3461 uint16_t* _to_nxt = _to;
3462 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3463 _Maxcode_, _Mode_);
3464 frm_nxt = frm + (_frm_nxt - _frm);
3465 to_nxt = to + (_to_nxt - _to);
3466 return r;
3467}
3468
3469__codecvt_utf16<char16_t, true>::result
3470__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3471 extern_type* to, extern_type*, extern_type*& to_nxt) const
3472{
3473 to_nxt = to;
3474 return noconv;
3475}
3476
3477int
Howard Hinnantc9834542011-05-31 15:34:58 +00003478__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003479{
3480 return 0;
3481}
3482
3483bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003484__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003485{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003486 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003487}
3488
3489int
3490__codecvt_utf16<char16_t, true>::do_length(state_type&,
3491 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3492{
3493 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3494 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3495 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3496}
3497
3498int
Howard Hinnantc9834542011-05-31 15:34:58 +00003499__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003500{
3501 if (_Mode_ & consume_header)
3502 return 4;
3503 return 2;
3504}
3505
3506// __codecvt_utf16<char32_t, false>
3507
3508__codecvt_utf16<char32_t, false>::result
3509__codecvt_utf16<char32_t, false>::do_out(state_type&,
3510 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3511 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3512{
3513 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3514 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3515 const uint32_t* _frm_nxt = _frm;
3516 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3517 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3518 uint8_t* _to_nxt = _to;
3519 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3520 _Maxcode_, _Mode_);
3521 frm_nxt = frm + (_frm_nxt - _frm);
3522 to_nxt = to + (_to_nxt - _to);
3523 return r;
3524}
3525
3526__codecvt_utf16<char32_t, false>::result
3527__codecvt_utf16<char32_t, false>::do_in(state_type&,
3528 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3529 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3530{
3531 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3532 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3533 const uint8_t* _frm_nxt = _frm;
3534 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3535 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3536 uint32_t* _to_nxt = _to;
3537 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3538 _Maxcode_, _Mode_);
3539 frm_nxt = frm + (_frm_nxt - _frm);
3540 to_nxt = to + (_to_nxt - _to);
3541 return r;
3542}
3543
3544__codecvt_utf16<char32_t, false>::result
3545__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3546 extern_type* to, extern_type*, extern_type*& to_nxt) const
3547{
3548 to_nxt = to;
3549 return noconv;
3550}
3551
3552int
Howard Hinnantc9834542011-05-31 15:34:58 +00003553__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003554{
3555 return 0;
3556}
3557
3558bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003559__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003560{
3561 return false;
3562}
3563
3564int
3565__codecvt_utf16<char32_t, false>::do_length(state_type&,
3566 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3567{
3568 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3569 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3570 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3571}
3572
3573int
Howard Hinnantc9834542011-05-31 15:34:58 +00003574__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003575{
3576 if (_Mode_ & consume_header)
3577 return 6;
3578 return 4;
3579}
3580
3581// __codecvt_utf16<char32_t, true>
3582
3583__codecvt_utf16<char32_t, true>::result
3584__codecvt_utf16<char32_t, true>::do_out(state_type&,
3585 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3586 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3587{
3588 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3589 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3590 const uint32_t* _frm_nxt = _frm;
3591 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3592 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3593 uint8_t* _to_nxt = _to;
3594 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3595 _Maxcode_, _Mode_);
3596 frm_nxt = frm + (_frm_nxt - _frm);
3597 to_nxt = to + (_to_nxt - _to);
3598 return r;
3599}
3600
3601__codecvt_utf16<char32_t, true>::result
3602__codecvt_utf16<char32_t, true>::do_in(state_type&,
3603 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3604 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3605{
3606 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3607 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3608 const uint8_t* _frm_nxt = _frm;
3609 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3610 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3611 uint32_t* _to_nxt = _to;
3612 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3613 _Maxcode_, _Mode_);
3614 frm_nxt = frm + (_frm_nxt - _frm);
3615 to_nxt = to + (_to_nxt - _to);
3616 return r;
3617}
3618
3619__codecvt_utf16<char32_t, true>::result
3620__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3621 extern_type* to, extern_type*, extern_type*& to_nxt) const
3622{
3623 to_nxt = to;
3624 return noconv;
3625}
3626
3627int
Howard Hinnantc9834542011-05-31 15:34:58 +00003628__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003629{
3630 return 0;
3631}
3632
3633bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003634__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003635{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003636 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003637}
3638
3639int
3640__codecvt_utf16<char32_t, true>::do_length(state_type&,
3641 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3642{
3643 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3644 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3645 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3646}
3647
3648int
Howard Hinnantc9834542011-05-31 15:34:58 +00003649__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003650{
3651 if (_Mode_ & consume_header)
3652 return 6;
3653 return 4;
3654}
3655
3656// __codecvt_utf8_utf16<wchar_t>
3657
3658__codecvt_utf8_utf16<wchar_t>::result
3659__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3660 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3661 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3662{
3663 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3664 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3665 const uint32_t* _frm_nxt = _frm;
3666 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3667 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3668 uint8_t* _to_nxt = _to;
3669 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3670 _Maxcode_, _Mode_);
3671 frm_nxt = frm + (_frm_nxt - _frm);
3672 to_nxt = to + (_to_nxt - _to);
3673 return r;
3674}
3675
3676__codecvt_utf8_utf16<wchar_t>::result
3677__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3678 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3679 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3680{
3681 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3682 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3683 const uint8_t* _frm_nxt = _frm;
3684 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3685 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3686 uint32_t* _to_nxt = _to;
3687 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3688 _Maxcode_, _Mode_);
3689 frm_nxt = frm + (_frm_nxt - _frm);
3690 to_nxt = to + (_to_nxt - _to);
3691 return r;
3692}
3693
3694__codecvt_utf8_utf16<wchar_t>::result
3695__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3696 extern_type* to, extern_type*, extern_type*& to_nxt) const
3697{
3698 to_nxt = to;
3699 return noconv;
3700}
3701
3702int
Howard Hinnantc9834542011-05-31 15:34:58 +00003703__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003704{
3705 return 0;
3706}
3707
3708bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003709__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003710{
3711 return false;
3712}
3713
3714int
3715__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3716 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3717{
3718 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3719 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3720 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3721}
3722
3723int
Howard Hinnantc9834542011-05-31 15:34:58 +00003724__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003725{
3726 if (_Mode_ & consume_header)
3727 return 7;
3728 return 4;
3729}
3730
3731// __codecvt_utf8_utf16<char16_t>
3732
3733__codecvt_utf8_utf16<char16_t>::result
3734__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3735 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3736 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3737{
3738 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3739 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3740 const uint16_t* _frm_nxt = _frm;
3741 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3742 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3743 uint8_t* _to_nxt = _to;
3744 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3745 _Maxcode_, _Mode_);
3746 frm_nxt = frm + (_frm_nxt - _frm);
3747 to_nxt = to + (_to_nxt - _to);
3748 return r;
3749}
3750
3751__codecvt_utf8_utf16<char16_t>::result
3752__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3753 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3754 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3755{
3756 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3757 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3758 const uint8_t* _frm_nxt = _frm;
3759 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3760 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3761 uint16_t* _to_nxt = _to;
3762 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3763 _Maxcode_, _Mode_);
3764 frm_nxt = frm + (_frm_nxt - _frm);
3765 to_nxt = to + (_to_nxt - _to);
3766 return r;
3767}
3768
3769__codecvt_utf8_utf16<char16_t>::result
3770__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3771 extern_type* to, extern_type*, extern_type*& to_nxt) const
3772{
3773 to_nxt = to;
3774 return noconv;
3775}
3776
3777int
Howard Hinnantc9834542011-05-31 15:34:58 +00003778__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003779{
3780 return 0;
3781}
3782
3783bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003784__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003785{
3786 return false;
3787}
3788
3789int
3790__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3791 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3792{
3793 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3794 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3795 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3796}
3797
3798int
Howard Hinnantc9834542011-05-31 15:34:58 +00003799__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003800{
3801 if (_Mode_ & consume_header)
3802 return 7;
3803 return 4;
3804}
3805
3806// __codecvt_utf8_utf16<char32_t>
3807
3808__codecvt_utf8_utf16<char32_t>::result
3809__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3810 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3811 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3812{
3813 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3814 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3815 const uint32_t* _frm_nxt = _frm;
3816 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3817 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3818 uint8_t* _to_nxt = _to;
3819 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3820 _Maxcode_, _Mode_);
3821 frm_nxt = frm + (_frm_nxt - _frm);
3822 to_nxt = to + (_to_nxt - _to);
3823 return r;
3824}
3825
3826__codecvt_utf8_utf16<char32_t>::result
3827__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3828 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3829 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3830{
3831 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3832 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3833 const uint8_t* _frm_nxt = _frm;
3834 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3835 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3836 uint32_t* _to_nxt = _to;
3837 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3838 _Maxcode_, _Mode_);
3839 frm_nxt = frm + (_frm_nxt - _frm);
3840 to_nxt = to + (_to_nxt - _to);
3841 return r;
3842}
3843
3844__codecvt_utf8_utf16<char32_t>::result
3845__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3846 extern_type* to, extern_type*, extern_type*& to_nxt) const
3847{
3848 to_nxt = to;
3849 return noconv;
3850}
3851
3852int
Howard Hinnantc9834542011-05-31 15:34:58 +00003853__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003854{
3855 return 0;
3856}
3857
3858bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003859__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003860{
3861 return false;
3862}
3863
3864int
3865__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3866 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3867{
3868 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3869 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3870 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3871}
3872
3873int
Howard Hinnantc9834542011-05-31 15:34:58 +00003874__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003875{
3876 if (_Mode_ & consume_header)
3877 return 7;
3878 return 4;
3879}
3880
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003881// __narrow_to_utf8<16>
3882
3883__narrow_to_utf8<16>::~__narrow_to_utf8()
3884{
3885}
3886
3887// __narrow_to_utf8<32>
3888
3889__narrow_to_utf8<32>::~__narrow_to_utf8()
3890{
3891}
3892
3893// __widen_from_utf8<16>
3894
3895__widen_from_utf8<16>::~__widen_from_utf8()
3896{
3897}
3898
3899// __widen_from_utf8<32>
3900
3901__widen_from_utf8<32>::~__widen_from_utf8()
3902{
3903}
3904
3905// numpunct<char> && numpunct<wchar_t>
3906
3907locale::id numpunct< char >::id;
3908locale::id numpunct<wchar_t>::id;
3909
3910numpunct<char>::numpunct(size_t refs)
3911 : locale::facet(refs),
3912 __decimal_point_('.'),
3913 __thousands_sep_(',')
3914{
3915}
3916
3917numpunct<wchar_t>::numpunct(size_t refs)
3918 : locale::facet(refs),
3919 __decimal_point_(L'.'),
3920 __thousands_sep_(L',')
3921{
3922}
3923
3924numpunct<char>::~numpunct()
3925{
3926}
3927
3928numpunct<wchar_t>::~numpunct()
3929{
3930}
3931
3932 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
3933wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
3934
3935 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
3936wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
3937
3938string numpunct< char >::do_grouping() const {return __grouping_;}
3939string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
3940
3941 string numpunct< char >::do_truename() const {return "true";}
3942wstring numpunct<wchar_t>::do_truename() const {return L"true";}
3943
3944 string numpunct< char >::do_falsename() const {return "false";}
3945wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
3946
3947// numpunct_byname<char>
3948
3949numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
3950 : numpunct<char>(refs)
3951{
3952 __init(nm);
3953}
3954
3955numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
3956 : numpunct<char>(refs)
3957{
3958 __init(nm.c_str());
3959}
3960
3961numpunct_byname<char>::~numpunct_byname()
3962{
3963}
3964
3965void
3966numpunct_byname<char>::__init(const char* nm)
3967{
Michael J. Spencer626916f2010-12-10 19:47:54 +00003968#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003969 if (strcmp(nm, "C") != 0)
3970 {
3971 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00003972#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003973 if (loc == 0)
3974 throw runtime_error("numpunct_byname<char>::numpunct_byname"
3975 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003976#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003977 lconv* lc = localeconv_l(loc.get());
3978 if (*lc->decimal_point)
3979 __decimal_point_ = *lc->decimal_point;
3980 if (*lc->thousands_sep)
3981 __thousands_sep_ = *lc->thousands_sep;
3982 __grouping_ = lc->grouping;
3983 // locallization for truename and falsename is not available
3984 }
Michael J. Spencer626916f2010-12-10 19:47:54 +00003985#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003986}
3987
3988// numpunct_byname<wchar_t>
3989
3990numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
3991 : numpunct<wchar_t>(refs)
3992{
3993 __init(nm);
3994}
3995
3996numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
3997 : numpunct<wchar_t>(refs)
3998{
3999 __init(nm.c_str());
4000}
4001
4002numpunct_byname<wchar_t>::~numpunct_byname()
4003{
4004}
4005
4006void
4007numpunct_byname<wchar_t>::__init(const char* nm)
4008{
Michael J. Spencer626916f2010-12-10 19:47:54 +00004009#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004010 if (strcmp(nm, "C") != 0)
4011 {
4012 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004013#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004014 if (loc == 0)
4015 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4016 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004017#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004018 lconv* lc = localeconv_l(loc.get());
4019 if (*lc->decimal_point)
4020 __decimal_point_ = *lc->decimal_point;
4021 if (*lc->thousands_sep)
4022 __thousands_sep_ = *lc->thousands_sep;
4023 __grouping_ = lc->grouping;
4024 // locallization for truename and falsename is not available
4025 }
Michael J. Spencer626916f2010-12-10 19:47:54 +00004026#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004027}
4028
4029// num_get helpers
4030
4031int
4032__num_get_base::__get_base(ios_base& iob)
4033{
4034 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4035 if (__basefield == ios_base::oct)
4036 return 8;
4037 else if (__basefield == ios_base::hex)
4038 return 16;
4039 else if (__basefield == 0)
4040 return 0;
4041 return 10;
4042}
4043
4044const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4045
4046void
4047__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4048 ios_base::iostate& __err)
4049{
4050 if (__grouping.size() != 0)
4051 {
4052 reverse(__g, __g_end);
4053 const char* __ig = __grouping.data();
4054 const char* __eg = __ig + __grouping.size();
4055 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4056 {
4057 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4058 {
4059 if (*__ig != *__r)
4060 {
4061 __err = ios_base::failbit;
4062 return;
4063 }
4064 }
4065 if (__eg - __ig > 1)
4066 ++__ig;
4067 }
4068 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4069 {
4070 if (*__ig < __g_end[-1] || __g_end[-1] == 0)
4071 __err = ios_base::failbit;
4072 }
4073 }
4074}
4075
4076void
4077__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4078 ios_base::fmtflags __flags)
4079{
4080 if (__flags & ios_base::showpos)
4081 *__fmtp++ = '+';
4082 if (__flags & ios_base::showbase)
4083 *__fmtp++ = '#';
4084 while(*__len)
4085 *__fmtp++ = *__len++;
4086 if ((__flags & ios_base::basefield) == ios_base::oct)
4087 *__fmtp = 'o';
4088 else if ((__flags & ios_base::basefield) == ios_base::hex)
4089 {
4090 if (__flags & ios_base::uppercase)
4091 *__fmtp = 'X';
4092 else
4093 *__fmtp = 'x';
4094 }
4095 else if (__signd)
4096 *__fmtp = 'd';
4097 else
4098 *__fmtp = 'u';
4099}
4100
4101bool
4102__num_put_base::__format_float(char* __fmtp, const char* __len,
4103 ios_base::fmtflags __flags)
4104{
4105 bool specify_precision = true;
4106 if (__flags & ios_base::showpos)
4107 *__fmtp++ = '+';
4108 if (__flags & ios_base::showpoint)
4109 *__fmtp++ = '#';
4110 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4111 bool uppercase = __flags & ios_base::uppercase;
4112 if (floatfield == (ios_base::fixed | ios_base::scientific))
4113 specify_precision = false;
4114 else
4115 {
4116 *__fmtp++ = '.';
4117 *__fmtp++ = '*';
4118 }
4119 while(*__len)
4120 *__fmtp++ = *__len++;
4121 if (floatfield == ios_base::fixed)
4122 {
4123 if (uppercase)
4124 *__fmtp = 'F';
4125 else
4126 *__fmtp = 'f';
4127 }
4128 else if (floatfield == ios_base::scientific)
4129 {
4130 if (uppercase)
4131 *__fmtp = 'E';
4132 else
4133 *__fmtp = 'e';
4134 }
4135 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4136 {
4137 if (uppercase)
4138 *__fmtp = 'A';
4139 else
4140 *__fmtp = 'a';
4141 }
4142 else
4143 {
4144 if (uppercase)
4145 *__fmtp = 'G';
4146 else
4147 *__fmtp = 'g';
4148 }
4149 return specify_precision;
4150}
4151
4152char*
4153__num_put_base::__identify_padding(char* __nb, char* __ne,
4154 const ios_base& __iob)
4155{
4156 switch (__iob.flags() & ios_base::adjustfield)
4157 {
4158 case ios_base::internal:
4159 if (__nb[0] == '-' || __nb[0] == '+')
4160 return __nb+1;
4161 if (__ne - __nb >= 2 && __nb[0] == '0'
4162 && (__nb[1] == 'x' || __nb[1] == 'X'))
4163 return __nb+2;
4164 break;
4165 case ios_base::left:
4166 return __ne;
4167 case ios_base::right:
4168 default:
4169 break;
4170 }
4171 return __nb;
4172}
4173
4174// time_get
4175
4176static
4177string*
4178init_weeks()
4179{
4180 static string weeks[14];
4181 weeks[0] = "Sunday";
4182 weeks[1] = "Monday";
4183 weeks[2] = "Tuesday";
4184 weeks[3] = "Wednesday";
4185 weeks[4] = "Thursday";
4186 weeks[5] = "Friday";
4187 weeks[6] = "Saturday";
4188 weeks[7] = "Sun";
4189 weeks[8] = "Mon";
4190 weeks[9] = "Tue";
4191 weeks[10] = "Wed";
4192 weeks[11] = "Thu";
4193 weeks[12] = "Fri";
4194 weeks[13] = "Sat";
4195 return weeks;
4196}
4197
4198static
4199wstring*
4200init_wweeks()
4201{
4202 static wstring weeks[14];
4203 weeks[0] = L"Sunday";
4204 weeks[1] = L"Monday";
4205 weeks[2] = L"Tuesday";
4206 weeks[3] = L"Wednesday";
4207 weeks[4] = L"Thursday";
4208 weeks[5] = L"Friday";
4209 weeks[6] = L"Saturday";
4210 weeks[7] = L"Sun";
4211 weeks[8] = L"Mon";
4212 weeks[9] = L"Tue";
4213 weeks[10] = L"Wed";
4214 weeks[11] = L"Thu";
4215 weeks[12] = L"Fri";
4216 weeks[13] = L"Sat";
4217 return weeks;
4218}
4219
4220template <>
4221const string*
4222__time_get_c_storage<char>::__weeks() const
4223{
4224 static const string* weeks = init_weeks();
4225 return weeks;
4226}
4227
4228template <>
4229const wstring*
4230__time_get_c_storage<wchar_t>::__weeks() const
4231{
4232 static const wstring* weeks = init_wweeks();
4233 return weeks;
4234}
4235
4236static
4237string*
4238init_months()
4239{
4240 static string months[24];
4241 months[0] = "January";
4242 months[1] = "February";
4243 months[2] = "March";
4244 months[3] = "April";
4245 months[4] = "May";
4246 months[5] = "June";
4247 months[6] = "July";
4248 months[7] = "August";
4249 months[8] = "September";
4250 months[9] = "October";
4251 months[10] = "November";
4252 months[11] = "December";
4253 months[12] = "Jan";
4254 months[13] = "Feb";
4255 months[14] = "Mar";
4256 months[15] = "Apr";
4257 months[16] = "May";
4258 months[17] = "Jun";
4259 months[18] = "Jul";
4260 months[19] = "Aug";
4261 months[20] = "Sep";
4262 months[21] = "Oct";
4263 months[22] = "Nov";
4264 months[23] = "Dec";
4265 return months;
4266}
4267
4268static
4269wstring*
4270init_wmonths()
4271{
4272 static wstring months[24];
4273 months[0] = L"January";
4274 months[1] = L"February";
4275 months[2] = L"March";
4276 months[3] = L"April";
4277 months[4] = L"May";
4278 months[5] = L"June";
4279 months[6] = L"July";
4280 months[7] = L"August";
4281 months[8] = L"September";
4282 months[9] = L"October";
4283 months[10] = L"November";
4284 months[11] = L"December";
4285 months[12] = L"Jan";
4286 months[13] = L"Feb";
4287 months[14] = L"Mar";
4288 months[15] = L"Apr";
4289 months[16] = L"May";
4290 months[17] = L"Jun";
4291 months[18] = L"Jul";
4292 months[19] = L"Aug";
4293 months[20] = L"Sep";
4294 months[21] = L"Oct";
4295 months[22] = L"Nov";
4296 months[23] = L"Dec";
4297 return months;
4298}
4299
4300template <>
4301const string*
4302__time_get_c_storage<char>::__months() const
4303{
4304 static const string* months = init_months();
4305 return months;
4306}
4307
4308template <>
4309const wstring*
4310__time_get_c_storage<wchar_t>::__months() const
4311{
4312 static const wstring* months = init_wmonths();
4313 return months;
4314}
4315
4316static
4317string*
4318init_am_pm()
4319{
4320 static string am_pm[24];
4321 am_pm[0] = "AM";
4322 am_pm[1] = "PM";
4323 return am_pm;
4324}
4325
4326static
4327wstring*
4328init_wam_pm()
4329{
4330 static wstring am_pm[24];
4331 am_pm[0] = L"AM";
4332 am_pm[1] = L"PM";
4333 return am_pm;
4334}
4335
4336template <>
4337const string*
4338__time_get_c_storage<char>::__am_pm() const
4339{
4340 static const string* am_pm = init_am_pm();
4341 return am_pm;
4342}
4343
4344template <>
4345const wstring*
4346__time_get_c_storage<wchar_t>::__am_pm() const
4347{
4348 static const wstring* am_pm = init_wam_pm();
4349 return am_pm;
4350}
4351
4352template <>
4353const string&
4354__time_get_c_storage<char>::__x() const
4355{
4356 static string s("%m/%d/%y");
4357 return s;
4358}
4359
4360template <>
4361const wstring&
4362__time_get_c_storage<wchar_t>::__x() const
4363{
4364 static wstring s(L"%m/%d/%y");
4365 return s;
4366}
4367
4368template <>
4369const string&
4370__time_get_c_storage<char>::__X() const
4371{
4372 static string s("%H:%M:%S");
4373 return s;
4374}
4375
4376template <>
4377const wstring&
4378__time_get_c_storage<wchar_t>::__X() const
4379{
4380 static wstring s(L"%H:%M:%S");
4381 return s;
4382}
4383
4384template <>
4385const string&
4386__time_get_c_storage<char>::__c() const
4387{
4388 static string s("%a %b %d %H:%M:%S %Y");
4389 return s;
4390}
4391
4392template <>
4393const wstring&
4394__time_get_c_storage<wchar_t>::__c() const
4395{
4396 static wstring s(L"%a %b %d %H:%M:%S %Y");
4397 return s;
4398}
4399
4400template <>
4401const string&
4402__time_get_c_storage<char>::__r() const
4403{
4404 static string s("%I:%M:%S %p");
4405 return s;
4406}
4407
4408template <>
4409const wstring&
4410__time_get_c_storage<wchar_t>::__r() const
4411{
4412 static wstring s(L"%I:%M:%S %p");
4413 return s;
4414}
4415
4416// time_get_byname
4417
4418__time_get::__time_get(const char* nm)
4419 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4420{
Howard Hinnantd4444702010-08-11 17:04:31 +00004421#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004422 if (__loc_ == 0)
4423 throw runtime_error("time_get_byname"
4424 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004425#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004426}
4427
4428__time_get::__time_get(const string& nm)
4429 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4430{
Howard Hinnantd4444702010-08-11 17:04:31 +00004431#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004432 if (__loc_ == 0)
4433 throw runtime_error("time_get_byname"
4434 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004435#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004436}
4437
4438__time_get::~__time_get()
4439{
4440 freelocale(__loc_);
4441}
4442
4443template <>
4444string
4445__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4446{
4447 tm t;
4448 t.tm_sec = 59;
4449 t.tm_min = 55;
4450 t.tm_hour = 23;
4451 t.tm_mday = 31;
4452 t.tm_mon = 11;
4453 t.tm_year = 161;
4454 t.tm_wday = 6;
4455 t.tm_yday = 364;
4456 t.tm_isdst = -1;
4457 char buf[100];
4458 char f[3] = {0};
4459 f[0] = '%';
4460 f[1] = fmt;
4461 size_t n = strftime_l(buf, 100, f, &t, __loc_);
4462 char* bb = buf;
4463 char* be = buf + n;
4464 string result;
4465 while (bb != be)
4466 {
4467 if (ct.is(ctype_base::space, *bb))
4468 {
4469 result.push_back(' ');
4470 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4471 ;
4472 continue;
4473 }
4474 char* w = bb;
4475 ios_base::iostate err = ios_base::goodbit;
4476 int i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4477 ct, err, false)
4478 - this->__weeks_;
4479 if (i < 14)
4480 {
4481 result.push_back('%');
4482 if (i < 7)
4483 result.push_back('A');
4484 else
4485 result.push_back('a');
4486 bb = w;
4487 continue;
4488 }
4489 w = bb;
4490 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4491 ct, err, false)
4492 - this->__months_;
4493 if (i < 24)
4494 {
4495 result.push_back('%');
4496 if (i < 12)
4497 result.push_back('B');
4498 else
4499 result.push_back('b');
4500 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4501 result.back() = 'm';
4502 bb = w;
4503 continue;
4504 }
4505 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4506 {
4507 w = bb;
4508 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4509 ct, err, false) - this->__am_pm_;
4510 if (i < 2)
4511 {
4512 result.push_back('%');
4513 result.push_back('p');
4514 bb = w;
4515 continue;
4516 }
4517 }
4518 w = bb;
4519 if (ct.is(ctype_base::digit, *bb))
4520 {
4521 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4522 {
4523 case 6:
4524 result.push_back('%');
4525 result.push_back('w');
4526 break;
4527 case 7:
4528 result.push_back('%');
4529 result.push_back('u');
4530 break;
4531 case 11:
4532 result.push_back('%');
4533 result.push_back('I');
4534 break;
4535 case 12:
4536 result.push_back('%');
4537 result.push_back('m');
4538 break;
4539 case 23:
4540 result.push_back('%');
4541 result.push_back('H');
4542 break;
4543 case 31:
4544 result.push_back('%');
4545 result.push_back('d');
4546 break;
4547 case 55:
4548 result.push_back('%');
4549 result.push_back('M');
4550 break;
4551 case 59:
4552 result.push_back('%');
4553 result.push_back('S');
4554 break;
4555 case 61:
4556 result.push_back('%');
4557 result.push_back('y');
4558 break;
4559 case 364:
4560 result.push_back('%');
4561 result.push_back('j');
4562 break;
4563 case 2061:
4564 result.push_back('%');
4565 result.push_back('Y');
4566 break;
4567 default:
4568 for (; w != bb; ++w)
4569 result.push_back(*w);
4570 break;
4571 }
4572 continue;
4573 }
4574 if (*bb == '%')
4575 {
4576 result.push_back('%');
4577 result.push_back('%');
4578 ++bb;
4579 continue;
4580 }
4581 result.push_back(*bb);
4582 ++bb;
4583 }
4584 return result;
4585}
4586
4587template <>
4588wstring
4589__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4590{
Michael J. Spencer626916f2010-12-10 19:47:54 +00004591#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004592 tm t;
4593 t.tm_sec = 59;
4594 t.tm_min = 55;
4595 t.tm_hour = 23;
4596 t.tm_mday = 31;
4597 t.tm_mon = 11;
4598 t.tm_year = 161;
4599 t.tm_wday = 6;
4600 t.tm_yday = 364;
4601 t.tm_isdst = -1;
4602 char buf[100];
4603 char f[3] = {0};
4604 f[0] = '%';
4605 f[1] = fmt;
4606 size_t be = strftime_l(buf, 100, f, &t, __loc_);
4607 wchar_t wbuf[100];
4608 wchar_t* wbb = wbuf;
4609 mbstate_t mb = {0};
4610 const char* bb = buf;
4611 size_t i = mbsrtowcs_l(wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4612 if (i == -1)
4613 __throw_runtime_error("locale not supported");
4614 wchar_t* wbe = wbb + i;
4615 wstring result;
4616 while (wbb != wbe)
4617 {
4618 if (ct.is(ctype_base::space, *wbb))
4619 {
4620 result.push_back(L' ');
4621 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4622 ;
4623 continue;
4624 }
4625 wchar_t* w = wbb;
4626 ios_base::iostate err = ios_base::goodbit;
4627 int i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4628 ct, err, false)
4629 - this->__weeks_;
4630 if (i < 14)
4631 {
4632 result.push_back(L'%');
4633 if (i < 7)
4634 result.push_back(L'A');
4635 else
4636 result.push_back(L'a');
4637 wbb = w;
4638 continue;
4639 }
4640 w = wbb;
4641 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4642 ct, err, false)
4643 - this->__months_;
4644 if (i < 24)
4645 {
4646 result.push_back(L'%');
4647 if (i < 12)
4648 result.push_back(L'B');
4649 else
4650 result.push_back(L'b');
4651 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4652 result.back() = L'm';
4653 wbb = w;
4654 continue;
4655 }
4656 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4657 {
4658 w = wbb;
4659 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4660 ct, err, false) - this->__am_pm_;
4661 if (i < 2)
4662 {
4663 result.push_back(L'%');
4664 result.push_back(L'p');
4665 wbb = w;
4666 continue;
4667 }
4668 }
4669 w = wbb;
4670 if (ct.is(ctype_base::digit, *wbb))
4671 {
4672 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4673 {
4674 case 6:
4675 result.push_back(L'%');
4676 result.push_back(L'w');
4677 break;
4678 case 7:
4679 result.push_back(L'%');
4680 result.push_back(L'u');
4681 break;
4682 case 11:
4683 result.push_back(L'%');
4684 result.push_back(L'I');
4685 break;
4686 case 12:
4687 result.push_back(L'%');
4688 result.push_back(L'm');
4689 break;
4690 case 23:
4691 result.push_back(L'%');
4692 result.push_back(L'H');
4693 break;
4694 case 31:
4695 result.push_back(L'%');
4696 result.push_back(L'd');
4697 break;
4698 case 55:
4699 result.push_back(L'%');
4700 result.push_back(L'M');
4701 break;
4702 case 59:
4703 result.push_back(L'%');
4704 result.push_back(L'S');
4705 break;
4706 case 61:
4707 result.push_back(L'%');
4708 result.push_back(L'y');
4709 break;
4710 case 364:
4711 result.push_back(L'%');
4712 result.push_back(L'j');
4713 break;
4714 case 2061:
4715 result.push_back(L'%');
4716 result.push_back(L'Y');
4717 break;
4718 default:
4719 for (; w != wbb; ++w)
4720 result.push_back(*w);
4721 break;
4722 }
4723 continue;
4724 }
4725 if (ct.narrow(*wbb, 0) == '%')
4726 {
4727 result.push_back(L'%');
4728 result.push_back(L'%');
4729 ++wbb;
4730 continue;
4731 }
4732 result.push_back(*wbb);
4733 ++wbb;
4734 }
4735 return result;
Michael J. Spencer626916f2010-12-10 19:47:54 +00004736#else
4737 return wstring();
4738#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004739}
4740
4741template <>
4742void
4743__time_get_storage<char>::init(const ctype<char>& ct)
4744{
4745 tm t;
4746 char buf[100];
4747 // __weeks_
4748 for (int i = 0; i < 7; ++i)
4749 {
4750 t.tm_wday = i;
4751 strftime_l(buf, 100, "%A", &t, __loc_);
4752 __weeks_[i] = buf;
4753 strftime_l(buf, 100, "%a", &t, __loc_);
4754 __weeks_[i+7] = buf;
4755 }
4756 // __months_
4757 for (int i = 0; i < 12; ++i)
4758 {
4759 t.tm_mon = i;
4760 strftime_l(buf, 100, "%B", &t, __loc_);
4761 __months_[i] = buf;
4762 strftime_l(buf, 100, "%b", &t, __loc_);
4763 __months_[i+12] = buf;
4764 }
4765 // __am_pm_
4766 t.tm_hour = 1;
4767 strftime_l(buf, 100, "%p", &t, __loc_);
4768 __am_pm_[0] = buf;
4769 t.tm_hour = 13;
4770 strftime_l(buf, 100, "%p", &t, __loc_);
4771 __am_pm_[1] = buf;
4772 __c_ = __analyze('c', ct);
4773 __r_ = __analyze('r', ct);
4774 __x_ = __analyze('x', ct);
4775 __X_ = __analyze('X', ct);
4776}
4777
4778template <>
4779void
4780__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4781{
Michael J. Spencer626916f2010-12-10 19:47:54 +00004782#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004783 tm t = {0};
4784 char buf[100];
4785 size_t be;
4786 wchar_t wbuf[100];
4787 wchar_t* wbe;
4788 mbstate_t mb = {0};
4789 // __weeks_
4790 for (int i = 0; i < 7; ++i)
4791 {
4792 t.tm_wday = i;
4793 be = strftime_l(buf, 100, "%A", &t, __loc_);
4794 mb = mbstate_t();
4795 const char* bb = buf;
4796 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4797 if (j == -1)
4798 __throw_runtime_error("locale not supported");
4799 wbe = wbuf + j;
4800 __weeks_[i].assign(wbuf, wbe);
4801 be = strftime_l(buf, 100, "%a", &t, __loc_);
4802 mb = mbstate_t();
4803 bb = buf;
4804 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4805 if (j == -1)
4806 __throw_runtime_error("locale not supported");
4807 wbe = wbuf + j;
4808 __weeks_[i+7].assign(wbuf, wbe);
4809 }
4810 // __months_
4811 for (int i = 0; i < 12; ++i)
4812 {
4813 t.tm_mon = i;
4814 be = strftime_l(buf, 100, "%B", &t, __loc_);
4815 mb = mbstate_t();
4816 const char* bb = buf;
4817 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4818 if (j == -1)
4819 __throw_runtime_error("locale not supported");
4820 wbe = wbuf + j;
4821 __months_[i].assign(wbuf, wbe);
4822 be = strftime_l(buf, 100, "%b", &t, __loc_);
4823 mb = mbstate_t();
4824 bb = buf;
4825 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4826 if (j == -1)
4827 __throw_runtime_error("locale not supported");
4828 wbe = wbuf + j;
4829 __months_[i+12].assign(wbuf, wbe);
4830 }
4831 // __am_pm_
4832 t.tm_hour = 1;
4833 be = strftime_l(buf, 100, "%p", &t, __loc_);
4834 mb = mbstate_t();
4835 const char* bb = buf;
4836 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4837 if (j == -1)
4838 __throw_runtime_error("locale not supported");
4839 wbe = wbuf + j;
4840 __am_pm_[0].assign(wbuf, wbe);
4841 t.tm_hour = 13;
4842 be = strftime_l(buf, 100, "%p", &t, __loc_);
4843 mb = mbstate_t();
4844 bb = buf;
4845 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4846 if (j == -1)
4847 __throw_runtime_error("locale not supported");
4848 wbe = wbuf + j;
4849 __am_pm_[1].assign(wbuf, wbe);
4850 __c_ = __analyze('c', ct);
4851 __r_ = __analyze('r', ct);
4852 __x_ = __analyze('x', ct);
4853 __X_ = __analyze('X', ct);
Michael J. Spencer626916f2010-12-10 19:47:54 +00004854#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004855}
4856
4857template <class CharT>
4858struct _LIBCPP_HIDDEN __time_get_temp
4859 : public ctype_byname<CharT>
4860{
4861 explicit __time_get_temp(const char* nm)
4862 : ctype_byname<CharT>(nm, 1) {}
4863 explicit __time_get_temp(const string& nm)
4864 : ctype_byname<CharT>(nm, 1) {}
4865};
4866
4867template <>
4868__time_get_storage<char>::__time_get_storage(const char* __nm)
4869 : __time_get(__nm)
4870{
4871 const __time_get_temp<char> ct(__nm);
4872 init(ct);
4873}
4874
4875template <>
4876__time_get_storage<char>::__time_get_storage(const string& __nm)
4877 : __time_get(__nm)
4878{
4879 const __time_get_temp<char> ct(__nm);
4880 init(ct);
4881}
4882
4883template <>
4884__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
4885 : __time_get(__nm)
4886{
4887 const __time_get_temp<wchar_t> ct(__nm);
4888 init(ct);
4889}
4890
4891template <>
4892__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
4893 : __time_get(__nm)
4894{
4895 const __time_get_temp<wchar_t> ct(__nm);
4896 init(ct);
4897}
4898
4899template <>
4900time_base::dateorder
4901__time_get_storage<char>::__do_date_order() const
4902{
4903 unsigned i;
4904 for (i = 0; i < __x_.size(); ++i)
4905 if (__x_[i] == '%')
4906 break;
4907 ++i;
4908 switch (__x_[i])
4909 {
4910 case 'y':
4911 case 'Y':
4912 for (++i; i < __x_.size(); ++i)
4913 if (__x_[i] == '%')
4914 break;
4915 if (i == __x_.size())
4916 break;
4917 ++i;
4918 switch (__x_[i])
4919 {
4920 case 'm':
4921 for (++i; i < __x_.size(); ++i)
4922 if (__x_[i] == '%')
4923 break;
4924 if (i == __x_.size())
4925 break;
4926 ++i;
4927 if (__x_[i] == 'd')
4928 return time_base::ymd;
4929 break;
4930 case 'd':
4931 for (++i; i < __x_.size(); ++i)
4932 if (__x_[i] == '%')
4933 break;
4934 if (i == __x_.size())
4935 break;
4936 ++i;
4937 if (__x_[i] == 'm')
4938 return time_base::ydm;
4939 break;
4940 }
4941 break;
4942 case 'm':
4943 for (++i; i < __x_.size(); ++i)
4944 if (__x_[i] == '%')
4945 break;
4946 if (i == __x_.size())
4947 break;
4948 ++i;
4949 if (__x_[i] == 'd')
4950 {
4951 for (++i; i < __x_.size(); ++i)
4952 if (__x_[i] == '%')
4953 break;
4954 if (i == __x_.size())
4955 break;
4956 ++i;
4957 if (__x_[i] == 'y' || __x_[i] == 'Y')
4958 return time_base::mdy;
4959 break;
4960 }
4961 break;
4962 case 'd':
4963 for (++i; i < __x_.size(); ++i)
4964 if (__x_[i] == '%')
4965 break;
4966 if (i == __x_.size())
4967 break;
4968 ++i;
4969 if (__x_[i] == 'm')
4970 {
4971 for (++i; i < __x_.size(); ++i)
4972 if (__x_[i] == '%')
4973 break;
4974 if (i == __x_.size())
4975 break;
4976 ++i;
4977 if (__x_[i] == 'y' || __x_[i] == 'Y')
4978 return time_base::dmy;
4979 break;
4980 }
4981 break;
4982 }
4983 return time_base::no_order;
4984}
4985
4986template <>
4987time_base::dateorder
4988__time_get_storage<wchar_t>::__do_date_order() const
4989{
4990 unsigned i;
4991 for (i = 0; i < __x_.size(); ++i)
4992 if (__x_[i] == L'%')
4993 break;
4994 ++i;
4995 switch (__x_[i])
4996 {
4997 case L'y':
4998 case L'Y':
4999 for (++i; i < __x_.size(); ++i)
5000 if (__x_[i] == L'%')
5001 break;
5002 if (i == __x_.size())
5003 break;
5004 ++i;
5005 switch (__x_[i])
5006 {
5007 case L'm':
5008 for (++i; i < __x_.size(); ++i)
5009 if (__x_[i] == L'%')
5010 break;
5011 if (i == __x_.size())
5012 break;
5013 ++i;
5014 if (__x_[i] == L'd')
5015 return time_base::ymd;
5016 break;
5017 case L'd':
5018 for (++i; i < __x_.size(); ++i)
5019 if (__x_[i] == L'%')
5020 break;
5021 if (i == __x_.size())
5022 break;
5023 ++i;
5024 if (__x_[i] == L'm')
5025 return time_base::ydm;
5026 break;
5027 }
5028 break;
5029 case L'm':
5030 for (++i; i < __x_.size(); ++i)
5031 if (__x_[i] == L'%')
5032 break;
5033 if (i == __x_.size())
5034 break;
5035 ++i;
5036 if (__x_[i] == L'd')
5037 {
5038 for (++i; i < __x_.size(); ++i)
5039 if (__x_[i] == L'%')
5040 break;
5041 if (i == __x_.size())
5042 break;
5043 ++i;
5044 if (__x_[i] == L'y' || __x_[i] == L'Y')
5045 return time_base::mdy;
5046 break;
5047 }
5048 break;
5049 case L'd':
5050 for (++i; i < __x_.size(); ++i)
5051 if (__x_[i] == L'%')
5052 break;
5053 if (i == __x_.size())
5054 break;
5055 ++i;
5056 if (__x_[i] == L'm')
5057 {
5058 for (++i; i < __x_.size(); ++i)
5059 if (__x_[i] == L'%')
5060 break;
5061 if (i == __x_.size())
5062 break;
5063 ++i;
5064 if (__x_[i] == L'y' || __x_[i] == L'Y')
5065 return time_base::dmy;
5066 break;
5067 }
5068 break;
5069 }
5070 return time_base::no_order;
5071}
5072
5073// time_put
5074
5075__time_put::__time_put(const char* nm)
5076 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5077{
Howard Hinnantd4444702010-08-11 17:04:31 +00005078#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005079 if (__loc_ == 0)
5080 throw runtime_error("time_put_byname"
5081 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005082#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005083}
5084
5085__time_put::__time_put(const string& nm)
5086 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5087{
Howard Hinnantd4444702010-08-11 17:04:31 +00005088#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005089 if (__loc_ == 0)
5090 throw runtime_error("time_put_byname"
5091 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005092#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005093}
5094
5095__time_put::~__time_put()
5096{
5097 if (__loc_)
5098 freelocale(__loc_);
5099}
5100
5101void
5102__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5103 char __fmt, char __mod) const
5104{
5105 char fmt[] = {'%', __fmt, __mod, 0};
5106 if (__mod != 0)
5107 swap(fmt[1], fmt[2]);
5108 size_t n = strftime_l(__nb, __ne-__nb, fmt, __tm, __loc_);
5109 __ne = __nb + n;
5110}
5111
5112void
5113__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5114 char __fmt, char __mod) const
5115{
Michael J. Spencer626916f2010-12-10 19:47:54 +00005116#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005117 char __nar[100];
5118 char* __ne = __nar + 100;
5119 __do_put(__nar, __ne, __tm, __fmt, __mod);
5120 mbstate_t mb = {0};
5121 const char* __nb = __nar;
5122 size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5123 if (j == -1)
5124 __throw_runtime_error("locale not supported");
5125 __we = __wb + j;
Michael J. Spencer626916f2010-12-10 19:47:54 +00005126#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005127}
5128
5129// moneypunct_byname
5130
5131static
5132void
5133__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5134{
5135 const char sign = static_cast<char>(money_base::sign);
5136 const char space = static_cast<char>(money_base::space);
5137 const char none = static_cast<char>(money_base::none);
5138 const char symbol = static_cast<char>(money_base::symbol);
5139 const char value = static_cast<char>(money_base::value);
5140 switch (cs_precedes)
5141 {
5142 case 0:
5143 switch (sign_posn)
5144 {
5145 case 0:
5146 pat.field[0] = sign;
5147 pat.field[1] = value;
5148 pat.field[3] = symbol;
5149 switch (sep_by_space)
5150 {
5151 case 0:
5152 pat.field[2] = none;
5153 return;
5154 case 1:
5155 case 2:
5156 pat.field[2] = space;
5157 return;
5158 default:
5159 break;
5160 }
5161 break;
5162 case 1:
5163 pat.field[0] = sign;
5164 pat.field[3] = symbol;
5165 switch (sep_by_space)
5166 {
5167 case 0:
5168 pat.field[1] = value;
5169 pat.field[2] = none;
5170 return;
5171 case 1:
5172 pat.field[1] = value;
5173 pat.field[2] = space;
5174 return;
5175 case 2:
5176 pat.field[1] = space;
5177 pat.field[2] = value;
5178 return;
5179 default:
5180 break;
5181 }
5182 break;
5183 case 2:
5184 pat.field[0] = value;
5185 pat.field[3] = sign;
5186 switch (sep_by_space)
5187 {
5188 case 0:
5189 pat.field[1] = none;
5190 pat.field[2] = symbol;
5191 return;
5192 case 1:
5193 pat.field[1] = space;
5194 pat.field[2] = symbol;
5195 return;
5196 case 2:
5197 pat.field[1] = symbol;
5198 pat.field[2] = space;
5199 return;
5200 default:
5201 break;
5202 }
5203 break;
5204 case 3:
5205 pat.field[0] = value;
5206 pat.field[3] = symbol;
5207 switch (sep_by_space)
5208 {
5209 case 0:
5210 pat.field[1] = none;
5211 pat.field[2] = sign;
5212 return;
5213 case 1:
5214 pat.field[1] = space;
5215 pat.field[2] = sign;
5216 return;
5217 case 2:
5218 pat.field[1] = sign;
5219 pat.field[2] = space;
5220 return;
5221 default:
5222 break;
5223 }
5224 break;
5225 case 4:
5226 pat.field[0] = value;
5227 pat.field[3] = sign;
5228 switch (sep_by_space)
5229 {
5230 case 0:
5231 pat.field[1] = none;
5232 pat.field[2] = symbol;
5233 return;
5234 case 1:
5235 pat.field[1] = space;
5236 pat.field[2] = symbol;
5237 return;
5238 case 2:
5239 pat.field[1] = symbol;
5240 pat.field[2] = space;
5241 return;
5242 default:
5243 break;
5244 }
5245 break;
5246 default:
5247 break;
5248 }
5249 break;
5250 case 1:
5251 switch (sign_posn)
5252 {
5253 case 0:
5254 pat.field[0] = sign;
5255 pat.field[1] = symbol;
5256 pat.field[3] = value;
5257 switch (sep_by_space)
5258 {
5259 case 0:
5260 pat.field[2] = none;
5261 return;
5262 case 1:
5263 case 2:
5264 pat.field[2] = space;
5265 return;
5266 default:
5267 break;
5268 }
5269 break;
5270 case 1:
5271 pat.field[0] = sign;
5272 pat.field[3] = value;
5273 switch (sep_by_space)
5274 {
5275 case 0:
5276 pat.field[1] = symbol;
5277 pat.field[2] = none;
5278 return;
5279 case 1:
5280 pat.field[1] = symbol;
5281 pat.field[2] = space;
5282 return;
5283 case 2:
5284 pat.field[1] = space;
5285 pat.field[2] = symbol;
5286 return;
5287 default:
5288 break;
5289 }
5290 break;
5291 case 2:
5292 pat.field[0] = symbol;
5293 pat.field[3] = sign;
5294 switch (sep_by_space)
5295 {
5296 case 0:
5297 pat.field[1] = none;
5298 pat.field[2] = value;
5299 return;
5300 case 1:
5301 pat.field[1] = space;
5302 pat.field[2] = value;
5303 return;
5304 case 2:
5305 pat.field[1] = value;
5306 pat.field[2] = space;
5307 return;
5308 default:
5309 break;
5310 }
5311 break;
5312 case 3:
5313 pat.field[0] = sign;
5314 pat.field[3] = value;
5315 switch (sep_by_space)
5316 {
5317 case 0:
5318 pat.field[1] = symbol;
5319 pat.field[2] = none;
5320 return;
5321 case 1:
5322 pat.field[1] = symbol;
5323 pat.field[2] = space;
5324 return;
5325 case 2:
5326 pat.field[1] = space;
5327 pat.field[2] = symbol;
5328 return;
5329 default:
5330 break;
5331 }
5332 break;
5333 case 4:
5334 pat.field[0] = symbol;
5335 pat.field[3] = value;
5336 switch (sep_by_space)
5337 {
5338 case 0:
5339 pat.field[1] = sign;
5340 pat.field[2] = none;
5341 return;
5342 case 1:
5343 pat.field[1] = sign;
5344 pat.field[2] = space;
5345 return;
5346 case 2:
5347 pat.field[1] = space;
5348 pat.field[2] = sign;
5349 return;
5350 default:
5351 break;
5352 }
5353 break;
5354 default:
5355 break;
5356 }
5357 break;
5358 default:
5359 break;
5360 }
5361 pat.field[0] = symbol;
5362 pat.field[1] = sign;
5363 pat.field[2] = none;
5364 pat.field[3] = value;
5365}
5366
5367template<>
5368void
5369moneypunct_byname<char, false>::init(const char* nm)
5370{
Michael J. Spencer626916f2010-12-10 19:47:54 +00005371#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005372 typedef moneypunct<char, false> base;
5373 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005374#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005375 if (loc == 0)
5376 throw runtime_error("moneypunct_byname"
5377 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005378#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005379 lconv* lc = localeconv_l(loc.get());
5380 if (*lc->mon_decimal_point)
5381 __decimal_point_ = *lc->mon_decimal_point;
5382 else
5383 __decimal_point_ = base::do_decimal_point();
5384 if (*lc->mon_thousands_sep)
5385 __thousands_sep_ = *lc->mon_thousands_sep;
5386 else
5387 __thousands_sep_ = base::do_thousands_sep();
5388 __grouping_ = lc->mon_grouping;
5389 __curr_symbol_ = lc->currency_symbol;
5390 if (lc->frac_digits != CHAR_MAX)
5391 __frac_digits_ = lc->frac_digits;
5392 else
5393 __frac_digits_ = base::do_frac_digits();
5394 if (lc->p_sign_posn == 0)
5395 __positive_sign_ = "()";
5396 else
5397 __positive_sign_ = lc->positive_sign;
5398 if (lc->n_sign_posn == 0)
5399 __negative_sign_ = "()";
5400 else
5401 __negative_sign_ = lc->negative_sign;
5402 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5403 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
Michael J. Spencer626916f2010-12-10 19:47:54 +00005404#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005405}
5406
5407template<>
5408void
5409moneypunct_byname<char, true>::init(const char* nm)
5410{
Michael J. Spencer626916f2010-12-10 19:47:54 +00005411#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005412 typedef moneypunct<char, true> base;
5413 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005414#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005415 if (loc == 0)
5416 throw runtime_error("moneypunct_byname"
5417 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005418#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005419 lconv* lc = localeconv_l(loc.get());
5420 if (*lc->mon_decimal_point)
5421 __decimal_point_ = *lc->mon_decimal_point;
5422 else
5423 __decimal_point_ = base::do_decimal_point();
5424 if (*lc->mon_thousands_sep)
5425 __thousands_sep_ = *lc->mon_thousands_sep;
5426 else
5427 __thousands_sep_ = base::do_thousands_sep();
5428 __grouping_ = lc->mon_grouping;
5429 __curr_symbol_ = lc->int_curr_symbol;
5430 if (lc->int_frac_digits != CHAR_MAX)
5431 __frac_digits_ = lc->int_frac_digits;
5432 else
5433 __frac_digits_ = base::do_frac_digits();
5434 if (lc->int_p_sign_posn == 0)
5435 __positive_sign_ = "()";
5436 else
5437 __positive_sign_ = lc->positive_sign;
5438 if (lc->int_n_sign_posn == 0)
5439 __negative_sign_ = "()";
5440 else
5441 __negative_sign_ = lc->negative_sign;
5442 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5443 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
Michael J. Spencer626916f2010-12-10 19:47:54 +00005444#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005445}
5446
5447template<>
5448void
5449moneypunct_byname<wchar_t, false>::init(const char* nm)
5450{
Michael J. Spencer626916f2010-12-10 19:47:54 +00005451#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005452 typedef moneypunct<wchar_t, false> base;
5453 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005454#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005455 if (loc == 0)
5456 throw runtime_error("moneypunct_byname"
5457 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005458#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005459 lconv* lc = localeconv_l(loc.get());
5460 if (*lc->mon_decimal_point)
5461 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5462 else
5463 __decimal_point_ = base::do_decimal_point();
5464 if (*lc->mon_thousands_sep)
5465 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5466 else
5467 __thousands_sep_ = base::do_thousands_sep();
5468 __grouping_ = lc->mon_grouping;
5469 wchar_t wbuf[100];
5470 mbstate_t mb = {0};
5471 const char* bb = lc->currency_symbol;
5472 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5473 if (j == -1)
5474 __throw_runtime_error("locale not supported");
5475 wchar_t* wbe = wbuf + j;
5476 __curr_symbol_.assign(wbuf, wbe);
5477 if (lc->frac_digits != CHAR_MAX)
5478 __frac_digits_ = lc->frac_digits;
5479 else
5480 __frac_digits_ = base::do_frac_digits();
5481 if (lc->p_sign_posn == 0)
5482 __positive_sign_ = L"()";
5483 else
5484 {
5485 mb = mbstate_t();
5486 bb = lc->positive_sign;
5487 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5488 if (j == -1)
5489 __throw_runtime_error("locale not supported");
5490 wbe = wbuf + j;
5491 __positive_sign_.assign(wbuf, wbe);
5492 }
5493 if (lc->n_sign_posn == 0)
5494 __negative_sign_ = L"()";
5495 else
5496 {
5497 mb = mbstate_t();
5498 bb = lc->negative_sign;
5499 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5500 if (j == -1)
5501 __throw_runtime_error("locale not supported");
5502 wbe = wbuf + j;
5503 __negative_sign_.assign(wbuf, wbe);
5504 }
5505 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5506 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
Michael J. Spencer626916f2010-12-10 19:47:54 +00005507#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005508}
5509
5510template<>
5511void
5512moneypunct_byname<wchar_t, true>::init(const char* nm)
5513{
Michael J. Spencer626916f2010-12-10 19:47:54 +00005514#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005515 typedef moneypunct<wchar_t, true> base;
5516 unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005517#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005518 if (loc == 0)
5519 throw runtime_error("moneypunct_byname"
5520 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005521#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005522 lconv* lc = localeconv_l(loc.get());
5523 if (*lc->mon_decimal_point)
5524 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5525 else
5526 __decimal_point_ = base::do_decimal_point();
5527 if (*lc->mon_thousands_sep)
5528 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5529 else
5530 __thousands_sep_ = base::do_thousands_sep();
5531 __grouping_ = lc->mon_grouping;
5532 wchar_t wbuf[100];
5533 mbstate_t mb = {0};
5534 const char* bb = lc->int_curr_symbol;
5535 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5536 if (j == -1)
5537 __throw_runtime_error("locale not supported");
5538 wchar_t* wbe = wbuf + j;
5539 __curr_symbol_.assign(wbuf, wbe);
5540 if (lc->int_frac_digits != CHAR_MAX)
5541 __frac_digits_ = lc->int_frac_digits;
5542 else
5543 __frac_digits_ = base::do_frac_digits();
5544 if (lc->int_p_sign_posn == 0)
5545 __positive_sign_ = L"()";
5546 else
5547 {
5548 mb = mbstate_t();
5549 bb = lc->positive_sign;
5550 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5551 if (j == -1)
5552 __throw_runtime_error("locale not supported");
5553 wbe = wbuf + j;
5554 __positive_sign_.assign(wbuf, wbe);
5555 }
5556 if (lc->int_n_sign_posn == 0)
5557 __negative_sign_ = L"()";
5558 else
5559 {
5560 mb = mbstate_t();
5561 bb = lc->negative_sign;
5562 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5563 if (j == -1)
5564 __throw_runtime_error("locale not supported");
5565 wbe = wbuf + j;
5566 __negative_sign_.assign(wbuf, wbe);
5567 }
5568 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5569 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
Michael J. Spencer626916f2010-12-10 19:47:54 +00005570#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005571}
5572
5573void __do_nothing(void*) {}
5574
5575void __throw_runtime_error(const char* msg)
5576{
Howard Hinnantd4444702010-08-11 17:04:31 +00005577#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005578 throw runtime_error(msg);
Howard Hinnantd4444702010-08-11 17:04:31 +00005579#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005580}
5581
5582template class collate<char>;
5583template class collate<wchar_t>;
5584
5585template class num_get<char>;
5586template class num_get<wchar_t>;
5587
5588template class __num_get<char>;
5589template class __num_get<wchar_t>;
5590
5591template class num_put<char>;
5592template class num_put<wchar_t>;
5593
5594template class __num_put<char>;
5595template class __num_put<wchar_t>;
5596
5597template class time_get<char>;
5598template class time_get<wchar_t>;
5599
5600template class time_get_byname<char>;
5601template class time_get_byname<wchar_t>;
5602
5603template class time_put<char>;
5604template class time_put<wchar_t>;
5605
5606template class time_put_byname<char>;
5607template class time_put_byname<wchar_t>;
5608
5609template class moneypunct<char, false>;
5610template class moneypunct<char, true>;
5611template class moneypunct<wchar_t, false>;
5612template class moneypunct<wchar_t, true>;
5613
5614template class moneypunct_byname<char, false>;
5615template class moneypunct_byname<char, true>;
5616template class moneypunct_byname<wchar_t, false>;
5617template class moneypunct_byname<wchar_t, true>;
5618
5619template class money_get<char>;
5620template class money_get<wchar_t>;
5621
5622template class __money_get<char>;
5623template class __money_get<wchar_t>;
5624
5625template class money_put<char>;
5626template class money_put<wchar_t>;
5627
5628template class __money_put<char>;
5629template class __money_put<wchar_t>;
5630
5631template class messages<char>;
5632template class messages<wchar_t>;
5633
5634template class messages_byname<char>;
5635template class messages_byname<wchar_t>;
5636
5637template class codecvt_byname<char, char, mbstate_t>;
5638template class codecvt_byname<wchar_t, char, mbstate_t>;
5639template class codecvt_byname<char16_t, char, mbstate_t>;
5640template class codecvt_byname<char32_t, char, mbstate_t>;
5641
5642template class __vector_base_common<true>;
5643
5644_LIBCPP_END_NAMESPACE_STD