blob: 8f1e4e1322bd29e61d08d74375ca892e1471287c [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"
Howard Hinnantd318d492011-06-30 14:21:55 +000017#include "type_traits"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000018#include "clocale"
19#include "cstring"
20#include "cwctype"
21#include "__sso_allocator"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000022#include <langinfo.h>
23#include <stdlib.h>
24
Sean Huntf3907e62011-07-15 05:40:33 +000025#ifdef _LIBCPP_STABLE_APPLE_ABI
Howard Hinnantd318d492011-06-30 14:21:55 +000026namespace {
Howard Hinnant0949eed2011-06-30 21:18:19 +000027 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
Howard Hinnantd318d492011-06-30 14:21:55 +000028 inline _LIBCPP_INLINE_VISIBILITY
29 mb_cur_max_l(locale_t loc)
30 {
31 return MB_CUR_MAX_L(loc);
32 }
Sean Huntf3907e62011-07-15 05:40:33 +000033}
Howard Hinnantd318d492011-06-30 14:21:55 +000034#endif
Howard Hinnantd318d492011-06-30 14:21:55 +000035
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000036_LIBCPP_BEGIN_NAMESPACE_STD
37
Howard Hinnant8caf4232011-07-31 17:16:32 +000038#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +000039locale_t __cloc() {
40 // In theory this could create a race condition. In practice
41 // the race condition is non-fatal since it will just create
42 // a little resource leak. Better approach would be appreciated.
43#ifdef __APPLE__
44 return 0;
45#else
46 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
47 return result;
48#endif
49}
Howard Hinnant8caf4232011-07-31 17:16:32 +000050#endif // _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +000051
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000052namespace {
53
54struct release
55{
56 void operator()(locale::facet* p) {p->__release_shared();}
57};
58
59template <class T, class A0>
60inline
61T&
62make(A0 a0)
63{
64 static typename aligned_storage<sizeof(T)>::type buf;
65 ::new (&buf) T(a0);
66 return *(T*)&buf;
67}
68
69template <class T, class A0, class A1>
70inline
71T&
72make(A0 a0, A1 a1)
73{
74 static typename aligned_storage<sizeof(T)>::type buf;
75 ::new (&buf) T(a0, a1);
76 return *(T*)&buf;
77}
78
79template <class T, class A0, class A1, class A2>
80inline
81T&
82make(A0 a0, A1 a1, A2 a2)
83{
84 static typename aligned_storage<sizeof(T)>::type buf;
85 ::new (&buf) T(a0, a1, a2);
86 return *(T*)&buf;
87}
88
89}
90
91class _LIBCPP_HIDDEN locale::__imp
92 : public facet
93{
94 enum {N = 28};
95 string name_;
96 vector<facet*, __sso_allocator<facet*, N> > facets_;
97public:
98 explicit __imp(size_t refs = 0);
99 explicit __imp(const string& name, size_t refs = 0);
100 __imp(const __imp&);
101 __imp(const __imp&, const string&, locale::category c);
102 __imp(const __imp& other, const __imp& one, locale::category c);
103 __imp(const __imp&, facet* f, long id);
104 ~__imp();
105
106 const string& name() const {return name_;}
107 bool has_facet(long id) const {return id < facets_.size() && facets_[id];}
108 const locale::facet* use_facet(long id) const;
109
110 static const locale& make_classic();
111 static locale& make_global();
112private:
113 void install(facet* f, long id);
114 template <class F> void install(F* f) {install(f, f->id.__get());}
115 template <class F> void install_from(const __imp& other);
116};
117
118locale::__imp::__imp(size_t refs)
119 : facet(refs),
120 name_("C"),
121 facets_(N)
122{
123 facets_.clear();
Howard Hinnant0949eed2011-06-30 21:18:19 +0000124 install(&make<_VSTD::collate<char> >(1));
125 install(&make<_VSTD::collate<wchar_t> >(1));
126 install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1));
127 install(&make<_VSTD::ctype<wchar_t> >(1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000128 install(&make<codecvt<char, char, mbstate_t> >(1));
129 install(&make<codecvt<wchar_t, char, mbstate_t> >(1));
130 install(&make<codecvt<char16_t, char, mbstate_t> >(1));
131 install(&make<codecvt<char32_t, char, mbstate_t> >(1));
132 install(&make<numpunct<char> >(1));
133 install(&make<numpunct<wchar_t> >(1));
134 install(&make<num_get<char> >(1));
135 install(&make<num_get<wchar_t> >(1));
136 install(&make<num_put<char> >(1));
137 install(&make<num_put<wchar_t> >(1));
138 install(&make<moneypunct<char, false> >(1));
139 install(&make<moneypunct<char, true> >(1));
140 install(&make<moneypunct<wchar_t, false> >(1));
141 install(&make<moneypunct<wchar_t, true> >(1));
142 install(&make<money_get<char> >(1));
143 install(&make<money_get<wchar_t> >(1));
144 install(&make<money_put<char> >(1));
145 install(&make<money_put<wchar_t> >(1));
146 install(&make<time_get<char> >(1));
147 install(&make<time_get<wchar_t> >(1));
148 install(&make<time_put<char> >(1));
149 install(&make<time_put<wchar_t> >(1));
Howard Hinnant0949eed2011-06-30 21:18:19 +0000150 install(&make<_VSTD::messages<char> >(1));
151 install(&make<_VSTD::messages<wchar_t> >(1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000152}
153
154locale::__imp::__imp(const string& name, size_t refs)
155 : facet(refs),
156 name_(name),
157 facets_(N)
158{
Howard Hinnantd4444702010-08-11 17:04:31 +0000159#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160 try
161 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000162#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000163 facets_ = locale::classic().__locale_->facets_;
164 for (unsigned i = 0; i < facets_.size(); ++i)
165 if (facets_[i])
166 facets_[i]->__add_shared();
167 install(new collate_byname<char>(name_));
168 install(new collate_byname<wchar_t>(name_));
169 install(new ctype_byname<char>(name_));
170 install(new ctype_byname<wchar_t>(name_));
171 install(new codecvt_byname<char, char, mbstate_t>(name_));
172 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
173 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
174 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
175 install(new numpunct_byname<char>(name_));
176 install(new numpunct_byname<wchar_t>(name_));
177 install(new moneypunct_byname<char, false>(name_));
178 install(new moneypunct_byname<char, true>(name_));
179 install(new moneypunct_byname<wchar_t, false>(name_));
180 install(new moneypunct_byname<wchar_t, true>(name_));
181 install(new time_get_byname<char>(name_));
182 install(new time_get_byname<wchar_t>(name_));
183 install(new time_put_byname<char>(name_));
184 install(new time_put_byname<wchar_t>(name_));
185 install(new messages_byname<char>(name_));
186 install(new messages_byname<wchar_t>(name_));
Howard Hinnantd4444702010-08-11 17:04:31 +0000187#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000188 }
189 catch (...)
190 {
191 for (unsigned i = 0; i < facets_.size(); ++i)
192 if (facets_[i])
193 facets_[i]->__release_shared();
194 throw;
195 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000196#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000197}
198
199locale::__imp::__imp(const __imp& other)
200 : name_(other.name_),
201 facets_(max<size_t>(N, other.facets_.size()))
202{
203 facets_ = other.facets_;
204 for (unsigned i = 0; i < facets_.size(); ++i)
205 if (facets_[i])
206 facets_[i]->__add_shared();
207}
208
209locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
210 : name_("*"),
211 facets_(N)
212{
213 facets_ = other.facets_;
214 for (unsigned i = 0; i < facets_.size(); ++i)
215 if (facets_[i])
216 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000217#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000218 try
219 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000220#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000221 if (c & locale::collate)
222 {
223 install(new collate_byname<char>(name));
224 install(new collate_byname<wchar_t>(name));
225 }
226 if (c & locale::ctype)
227 {
228 install(new ctype_byname<char>(name));
229 install(new ctype_byname<wchar_t>(name));
230 install(new codecvt_byname<char, char, mbstate_t>(name));
231 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
232 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
233 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
234 }
235 if (c & locale::monetary)
236 {
237 install(new moneypunct_byname<char, false>(name));
238 install(new moneypunct_byname<char, true>(name));
239 install(new moneypunct_byname<wchar_t, false>(name));
240 install(new moneypunct_byname<wchar_t, true>(name));
241 }
242 if (c & locale::numeric)
243 {
244 install(new numpunct_byname<char>(name));
245 install(new numpunct_byname<wchar_t>(name));
246 }
247 if (c & locale::time)
248 {
249 install(new time_get_byname<char>(name));
250 install(new time_get_byname<wchar_t>(name));
251 install(new time_put_byname<char>(name));
252 install(new time_put_byname<wchar_t>(name));
253 }
254 if (c & locale::messages)
255 {
256 install(new messages_byname<char>(name));
257 install(new messages_byname<wchar_t>(name));
258 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000259#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000260 }
261 catch (...)
262 {
263 for (unsigned i = 0; i < facets_.size(); ++i)
264 if (facets_[i])
265 facets_[i]->__release_shared();
266 throw;
267 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000268#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269}
270
271template<class F>
272inline
273void
274locale::__imp::install_from(const locale::__imp& one)
275{
276 long id = F::id.__get();
277 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
278}
279
280locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
281 : name_("*"),
282 facets_(N)
283{
284 facets_ = other.facets_;
285 for (unsigned i = 0; i < facets_.size(); ++i)
286 if (facets_[i])
287 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000288#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 try
290 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000291#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 if (c & locale::collate)
293 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000294 install_from<_VSTD::collate<char> >(one);
295 install_from<_VSTD::collate<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000296 }
297 if (c & locale::ctype)
298 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000299 install_from<_VSTD::ctype<char> >(one);
300 install_from<_VSTD::ctype<wchar_t> >(one);
301 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
302 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
303 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
304 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000305 }
306 if (c & locale::monetary)
307 {
308 install_from<moneypunct<char, false> >(one);
309 install_from<moneypunct<char, true> >(one);
310 install_from<moneypunct<wchar_t, false> >(one);
311 install_from<moneypunct<wchar_t, true> >(one);
312 install_from<money_get<char> >(one);
313 install_from<money_get<wchar_t> >(one);
314 install_from<money_put<char> >(one);
315 install_from<money_put<wchar_t> >(one);
316 }
317 if (c & locale::numeric)
318 {
319 install_from<numpunct<char> >(one);
320 install_from<numpunct<wchar_t> >(one);
321 install_from<num_get<char> >(one);
322 install_from<num_get<wchar_t> >(one);
323 install_from<num_put<char> >(one);
324 install_from<num_put<wchar_t> >(one);
325 }
326 if (c & locale::time)
327 {
328 install_from<time_get<char> >(one);
329 install_from<time_get<wchar_t> >(one);
330 install_from<time_put<char> >(one);
331 install_from<time_put<wchar_t> >(one);
332 }
333 if (c & locale::messages)
334 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000335 install_from<_VSTD::messages<char> >(one);
336 install_from<_VSTD::messages<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000337 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000338#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000339 }
340 catch (...)
341 {
342 for (unsigned i = 0; i < facets_.size(); ++i)
343 if (facets_[i])
344 facets_[i]->__release_shared();
345 throw;
346 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000347#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000348}
349
350locale::__imp::__imp(const __imp& other, facet* f, long id)
351 : name_("*"),
352 facets_(max<size_t>(N, other.facets_.size()+1))
353{
354 f->__add_shared();
355 unique_ptr<facet, release> hold(f);
356 facets_ = other.facets_;
357 for (unsigned i = 0; i < other.facets_.size(); ++i)
358 if (facets_[i])
359 facets_[i]->__add_shared();
360 install(hold.get(), id);
361}
362
363locale::__imp::~__imp()
364{
365 for (unsigned i = 0; i < facets_.size(); ++i)
366 if (facets_[i])
367 facets_[i]->__release_shared();
368}
369
370void
371locale::__imp::install(facet* f, long id)
372{
373 f->__add_shared();
374 unique_ptr<facet, release> hold(f);
375 if (id >= facets_.size())
376 facets_.resize(id+1);
377 if (facets_[id])
378 facets_[id]->__release_shared();
379 facets_[id] = hold.release();
380}
381
382const locale::facet*
383locale::__imp::use_facet(long id) const
384{
Howard Hinnantd4444702010-08-11 17:04:31 +0000385#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000386 if (!has_facet(id))
387 throw bad_cast();
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000388#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389 return facets_[id];
390}
391
392// locale
393
394const locale&
395locale::__imp::make_classic()
396{
397 // only one thread can get in here and it only gets in once
398 static aligned_storage<sizeof(locale)>::type buf;
399 locale* c = (locale*)&buf;
400 c->__locale_ = &make<__imp>(1);
401 return *c;
402}
403
404const locale&
405locale::classic()
406{
407 static const locale& c = __imp::make_classic();
408 return c;
409}
410
411locale&
412locale::__imp::make_global()
413{
414 // only one thread can get in here and it only gets in once
415 static aligned_storage<sizeof(locale)>::type buf;
416 locale* g = (locale*)&buf;
417 ::new (&buf) locale(locale::classic());
418 return *(locale*)&buf;
419}
420
421locale&
422locale::__global()
423{
424 static locale& g = __imp::make_global();
425 return g;
426}
427
Howard Hinnantc9834542011-05-31 15:34:58 +0000428locale::locale() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000429 : __locale_(__global().__locale_)
430{
431 __locale_->__add_shared();
432}
433
Howard Hinnantc9834542011-05-31 15:34:58 +0000434locale::locale(const locale& l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000435 : __locale_(l.__locale_)
436{
437 __locale_->__add_shared();
438}
439
Howard Hinnantc9834542011-05-31 15:34:58 +0000440locale::~locale()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441{
442 __locale_->__release_shared();
443}
444
445const locale&
Howard Hinnantc9834542011-05-31 15:34:58 +0000446locale::operator=(const locale& other) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447{
448 other.__locale_->__add_shared();
449 __locale_->__release_shared();
450 __locale_ = other.__locale_;
451 return *this;
452}
453
454locale::locale(const char* name)
Howard Hinnantd4444702010-08-11 17:04:31 +0000455#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000456 : __locale_(name ? new __imp(name)
457 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000458#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000459 : __locale_(new __imp(name))
460#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000461{
462 __locale_->__add_shared();
463}
464
465locale::locale(const string& name)
466 : __locale_(new __imp(name))
467{
468 __locale_->__add_shared();
469}
470
471locale::locale(const locale& other, const char* name, category c)
Howard Hinnantd4444702010-08-11 17:04:31 +0000472#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473 : __locale_(name ? new __imp(*other.__locale_, name, c)
474 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000475#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000476 : __locale_(new __imp(*other.__locale_, name, c))
477#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478{
479 __locale_->__add_shared();
480}
481
482locale::locale(const locale& other, const string& name, category c)
483 : __locale_(new __imp(*other.__locale_, name, c))
484{
485 __locale_->__add_shared();
486}
487
488locale::locale(const locale& other, const locale& one, category c)
489 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
490{
491 __locale_->__add_shared();
492}
493
494string
495locale::name() const
496{
497 return __locale_->name();
498}
499
500void
501locale::__install_ctor(const locale& other, facet* f, long id)
502{
503 if (f)
504 __locale_ = new __imp(*other.__locale_, f, id);
505 else
506 __locale_ = other.__locale_;
507 __locale_->__add_shared();
508}
509
510locale
511locale::global(const locale& loc)
512{
513 locale& g = __global();
514 locale r = g;
515 g = loc;
516 if (g.name() != "*")
517 setlocale(LC_ALL, g.name().c_str());
518 return r;
519}
520
521bool
522locale::has_facet(id& x) const
523{
524 return __locale_->has_facet(x.__get());
525}
526
527const locale::facet*
528locale::use_facet(id& x) const
529{
530 return __locale_->use_facet(x.__get());
531}
532
533bool
534locale::operator==(const locale& y) const
535{
536 return (__locale_ == y.__locale_)
537 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
538}
539
540// locale::facet
541
542locale::facet::~facet()
543{
544}
545
546void
Howard Hinnant1694d232011-05-28 14:41:13 +0000547locale::facet::__on_zero_shared() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000548{
549 delete this;
550}
551
552// locale::id
553
554int32_t locale::id::__next_id = 0;
555
556namespace
557{
558
559class __fake_bind
560{
561 locale::id* id_;
562 void (locale::id::* pmf_)();
563public:
564 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
565 : id_(id), pmf_(pmf) {}
566
567 void operator()() const
568 {
569 (id_->*pmf_)();
570 }
571};
572
573}
574
575long
576locale::id::__get()
577{
578 call_once(__flag_, __fake_bind(&locale::id::__init, this));
579 return __id_ - 1;
580}
581
582void
583locale::id::__init()
584{
Howard Hinnantadff4892010-05-24 17:49:41 +0000585 __id_ = __sync_add_and_fetch(&__next_id, 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000586}
587
588// template <> class collate_byname<char>
589
590collate_byname<char>::collate_byname(const char* n, size_t refs)
591 : collate<char>(refs),
592 __l(newlocale(LC_ALL_MASK, n, 0))
593{
Howard Hinnantd4444702010-08-11 17:04:31 +0000594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000595 if (__l == 0)
596 throw runtime_error("collate_byname<char>::collate_byname"
597 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000598#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000599}
600
601collate_byname<char>::collate_byname(const string& name, size_t refs)
602 : collate<char>(refs),
603 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
604{
Howard Hinnantd4444702010-08-11 17:04:31 +0000605#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000606 if (__l == 0)
607 throw runtime_error("collate_byname<char>::collate_byname"
608 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000609#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000610}
611
612collate_byname<char>::~collate_byname()
613{
614 freelocale(__l);
615}
616
617int
618collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
619 const char_type* __lo2, const char_type* __hi2) const
620{
621 string_type lhs(__lo1, __hi1);
622 string_type rhs(__lo2, __hi2);
623 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
624 if (r < 0)
625 return -1;
626 if (r > 0)
627 return 1;
628 return r;
629}
630
631collate_byname<char>::string_type
632collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
633{
634 const string_type in(lo, hi);
635 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
636 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
637 return out;
638}
639
640// template <> class collate_byname<wchar_t>
641
642collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
643 : collate<wchar_t>(refs),
644 __l(newlocale(LC_ALL_MASK, n, 0))
645{
Howard Hinnantd4444702010-08-11 17:04:31 +0000646#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000647 if (__l == 0)
648 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
649 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000650#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000651}
652
653collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
654 : collate<wchar_t>(refs),
655 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
656{
Howard Hinnantd4444702010-08-11 17:04:31 +0000657#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000658 if (__l == 0)
659 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
660 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000661#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000662}
663
664collate_byname<wchar_t>::~collate_byname()
665{
666 freelocale(__l);
667}
668
669int
670collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
671 const char_type* __lo2, const char_type* __hi2) const
672{
673 string_type lhs(__lo1, __hi1);
674 string_type rhs(__lo2, __hi2);
675 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
676 if (r < 0)
677 return -1;
678 if (r > 0)
679 return 1;
680 return r;
681}
682
683collate_byname<wchar_t>::string_type
684collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
685{
686 const string_type in(lo, hi);
687 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
688 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
689 return out;
690}
691
692// template <> class ctype<wchar_t>;
693
694locale::id ctype<wchar_t>::id;
695
696ctype<wchar_t>::~ctype()
697{
698}
699
700bool
701ctype<wchar_t>::do_is(mask m, char_type c) const
702{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000703 return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704}
705
706const wchar_t*
707ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
708{
709 for (; low != high; ++low, ++vec)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000710 *vec = static_cast<mask>(isascii(*low) ?
711 ctype<char>::classic_table()[*low] : 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000712 return low;
713}
714
715const wchar_t*
716ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
717{
718 for (; low != high; ++low)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000719 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000720 break;
721 return low;
722}
723
724const wchar_t*
725ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
726{
727 for (; low != high; ++low)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000728 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000729 break;
730 return low;
731}
732
733wchar_t
734ctype<wchar_t>::do_toupper(char_type c) const
735{
David Chisnallc512df12011-09-21 08:39:44 +0000736#if !(defined(_LIBCPP_STABLE_APPLE_ABI) || defined(__FreeBSD__))
Sean Hunt62a6ac32011-07-09 00:56:23 +0000737 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000738#else
739 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
740#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000741}
742
743const wchar_t*
744ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
745{
746 for (; low != high; ++low)
David Chisnallc512df12011-09-21 08:39:44 +0000747#if !(defined(_LIBCPP_STABLE_APPLE_ABI) || defined(__FreeBSD__))
Sean Hunt62a6ac32011-07-09 00:56:23 +0000748 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
749 : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000750#else
751 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
752#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000753 return low;
754}
755
756wchar_t
757ctype<wchar_t>::do_tolower(char_type c) const
758{
Sean Hunte59f7242011-07-09 01:09:31 +0000759#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000760 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000761#else
762 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
763#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764}
765
766const wchar_t*
767ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
768{
769 for (; low != high; ++low)
Sean Hunte59f7242011-07-09 01:09:31 +0000770#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000771 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
772 : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000773#else
774 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
775#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000776 return low;
777}
778
779wchar_t
780ctype<wchar_t>::do_widen(char c) const
781{
782 return c;
783}
784
785const char*
786ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
787{
788 for (; low != high; ++low, ++dest)
789 *dest = *low;
790 return low;
791}
792
793char
794ctype<wchar_t>::do_narrow(char_type c, char dfault) const
795{
796 if (isascii(c))
797 return static_cast<char>(c);
798 return dfault;
799}
800
801const wchar_t*
802ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
803{
804 for (; low != high; ++low, ++dest)
805 if (isascii(*low))
806 *dest = *low;
807 else
808 *dest = dfault;
809 return low;
810}
811
812// template <> class ctype<char>;
813
814locale::id ctype<char>::id;
815
816ctype<char>::ctype(const mask* tab, bool del, size_t refs)
817 : locale::facet(refs),
818 __tab_(tab),
819 __del_(del)
820{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000821 if (__tab_ == 0)
822 __tab_ = classic_table();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000823}
824
825ctype<char>::~ctype()
826{
827 if (__tab_ && __del_)
828 delete [] __tab_;
829}
830
831char
832ctype<char>::do_toupper(char_type c) const
833{
Sean Hunte59f7242011-07-09 01:09:31 +0000834#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000835 return isascii(c) ? __classic_upper_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000836#else
837 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
838#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000839}
840
841const char*
842ctype<char>::do_toupper(char_type* low, const char_type* high) const
843{
844 for (; low != high; ++low)
Sean Hunte59f7242011-07-09 01:09:31 +0000845#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000846 *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000847#else
Howard Hinnant66f26412011-07-09 19:47:01 +0000848 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000849#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850 return low;
851}
852
853char
854ctype<char>::do_tolower(char_type c) const
855{
Sean Hunte59f7242011-07-09 01:09:31 +0000856#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000857 return isascii(c) ? __classic_lower_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000858#else
859 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
860#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000861}
862
863const char*
864ctype<char>::do_tolower(char_type* low, const char_type* high) const
865{
866 for (; low != high; ++low)
Sean Hunte59f7242011-07-09 01:09:31 +0000867#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000868 *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000869#else
Howard Hinnant66f26412011-07-09 19:47:01 +0000870 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000871#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000872 return low;
873}
874
875char
876ctype<char>::do_widen(char c) const
877{
878 return c;
879}
880
881const char*
882ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
883{
884 for (; low != high; ++low, ++dest)
885 *dest = *low;
886 return low;
887}
888
889char
890ctype<char>::do_narrow(char_type c, char dfault) const
891{
892 if (isascii(c))
893 return static_cast<char>(c);
894 return dfault;
895}
896
897const char*
898ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
899{
900 for (; low != high; ++low, ++dest)
901 if (isascii(*low))
902 *dest = *low;
903 else
904 *dest = dfault;
905 return low;
906}
907
908const ctype<char>::mask*
Howard Hinnantc9834542011-05-31 15:34:58 +0000909ctype<char>::classic_table() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000910{
David Chisnallc512df12011-09-21 08:39:44 +0000911#if defined(__APPLE__) || defined(__FreeBSD__)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000912 return _DefaultRuneLocale.__runetype;
Sean Hunt62a6ac32011-07-09 00:56:23 +0000913#elif defined(__GLIBC__)
914 return __cloc()->__ctype_b;
David Chisnallc512df12011-09-21 08:39:44 +0000915// This is assumed to be safe, which is a nonsense assumption because we're
916// going to end up dereferencing it later...
Sean Hunt62a6ac32011-07-09 00:56:23 +0000917#else
918 return NULL;
919#endif
920}
921
Howard Hinnant66f26412011-07-09 19:47:01 +0000922#ifndef _LIBCPP_STABLE_APPLE_ABI
Sean Hunt62a6ac32011-07-09 00:56:23 +0000923const int*
924ctype<char>::__classic_lower_table() _NOEXCEPT
925{
David Chisnallc512df12011-09-21 08:39:44 +0000926#if defined(__APPLE__) || defined(__FreeBSD__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000927 return _DefaultRuneLocale.__maplower;
928#elif defined(__GLIBC__)
929 return __cloc()->__ctype_tolower;
930#else
931 return NULL;
932#endif
933}
934
935const int*
936ctype<char>::__classic_upper_table() _NOEXCEPT
937{
David Chisnallc512df12011-09-21 08:39:44 +0000938#if defined(__APPLE__) || defined(__FreeBSD__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000939 return _DefaultRuneLocale.__mapupper;
940#elif defined(__GLIBC__)
941 return __cloc()->__ctype_toupper;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000942#else
943 return NULL;
944#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000945}
Howard Hinnant8caf4232011-07-31 17:16:32 +0000946#endif // _LIBCPP_STABLE_APPLE_ABI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000947
948// template <> class ctype_byname<char>
949
950ctype_byname<char>::ctype_byname(const char* name, size_t refs)
951 : ctype<char>(0, false, refs),
952 __l(newlocale(LC_ALL_MASK, name, 0))
953{
Howard Hinnantd4444702010-08-11 17:04:31 +0000954#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000955 if (__l == 0)
956 throw runtime_error("ctype_byname<char>::ctype_byname"
957 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000958#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000959}
960
961ctype_byname<char>::ctype_byname(const string& name, size_t refs)
962 : ctype<char>(0, false, refs),
963 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
964{
Howard Hinnantd4444702010-08-11 17:04:31 +0000965#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000966 if (__l == 0)
967 throw runtime_error("ctype_byname<char>::ctype_byname"
968 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000969#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000970}
971
972ctype_byname<char>::~ctype_byname()
973{
974 freelocale(__l);
975}
976
977char
978ctype_byname<char>::do_toupper(char_type c) const
979{
980 return toupper_l(c, __l);
981}
982
983const char*
984ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
985{
986 for (; low != high; ++low)
987 *low = toupper_l(*low, __l);
988 return low;
989}
990
991char
992ctype_byname<char>::do_tolower(char_type c) const
993{
994 return tolower_l(c, __l);
995}
996
997const char*
998ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
999{
1000 for (; low != high; ++low)
1001 *low = tolower_l(*low, __l);
1002 return low;
1003}
1004
1005// template <> class ctype_byname<wchar_t>
1006
1007ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1008 : ctype<wchar_t>(refs),
1009 __l(newlocale(LC_ALL_MASK, name, 0))
1010{
Howard Hinnantd4444702010-08-11 17:04:31 +00001011#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001012 if (__l == 0)
1013 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1014 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001015#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001016}
1017
1018ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1019 : ctype<wchar_t>(refs),
1020 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1021{
Howard Hinnantd4444702010-08-11 17:04:31 +00001022#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001023 if (__l == 0)
1024 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1025 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001026#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001027}
1028
1029ctype_byname<wchar_t>::~ctype_byname()
1030{
1031 freelocale(__l);
1032}
1033
1034bool
1035ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1036{
Sean Hunt6f0342c2011-07-09 03:40:04 +00001037#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038 return static_cast<bool>(iswctype_l(c, m, __l));
Sean Hunt6f0342c2011-07-09 03:40:04 +00001039#else
David Chisnallc512df12011-09-21 08:39:44 +00001040 // FIXME: This is broken for things that test more than one flag.
Sean Hunt6f0342c2011-07-09 03:40:04 +00001041 if (m & space && !iswspace_l(c, __l)) return false;
1042 if (m & print && !iswprint_l(c, __l)) return false;
1043 if (m & cntrl && !iswcntrl_l(c, __l)) return false;
1044 if (m & upper && !iswupper_l(c, __l)) return false;
1045 if (m & lower && !iswlower_l(c, __l)) return false;
1046 if (m & alpha && !iswalpha_l(c, __l)) return false;
1047 if (m & digit && !iswdigit_l(c, __l)) return false;
1048 if (m & punct && !iswpunct_l(c, __l)) return false;
1049 if (m & xdigit && !iswxdigit_l(c, __l)) return false;
1050 if (m & blank && !iswblank_l(c, __l)) return false;
1051 return true;
1052#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001053}
1054
1055const wchar_t*
1056ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1057{
1058 for (; low != high; ++low, ++vec)
1059 {
1060 if (isascii(*low))
Sean Hunt62a6ac32011-07-09 00:56:23 +00001061 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001062 else
1063 {
1064 *vec = 0;
1065 if (iswspace_l(*low, __l))
1066 *vec |= space;
1067 if (iswprint_l(*low, __l))
1068 *vec |= print;
1069 if (iswcntrl_l(*low, __l))
1070 *vec |= cntrl;
1071 if (iswupper_l(*low, __l))
1072 *vec |= upper;
1073 if (iswlower_l(*low, __l))
1074 *vec |= lower;
1075 if (iswalpha_l(*low, __l))
1076 *vec |= alpha;
1077 if (iswdigit_l(*low, __l))
1078 *vec |= digit;
1079 if (iswpunct_l(*low, __l))
1080 *vec |= punct;
1081 if (iswxdigit_l(*low, __l))
1082 *vec |= xdigit;
1083 }
1084 }
1085 return low;
1086}
1087
1088const wchar_t*
1089ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1090{
1091 for (; low != high; ++low)
Sean Hunt6f0342c2011-07-09 03:40:04 +00001092 {
1093#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001094 if (iswctype_l(*low, m, __l))
1095 break;
Sean Hunt6f0342c2011-07-09 03:40:04 +00001096#else
1097 if (m & space && !iswspace_l(*low, __l)) continue;
1098 if (m & print && !iswprint_l(*low, __l)) continue;
1099 if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
1100 if (m & upper && !iswupper_l(*low, __l)) continue;
1101 if (m & lower && !iswlower_l(*low, __l)) continue;
1102 if (m & alpha && !iswalpha_l(*low, __l)) continue;
1103 if (m & digit && !iswdigit_l(*low, __l)) continue;
1104 if (m & punct && !iswpunct_l(*low, __l)) continue;
1105 if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
1106 if (m & blank && !iswblank_l(*low, __l)) continue;
1107 break;
1108#endif
1109 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001110 return low;
1111}
1112
1113const wchar_t*
1114ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1115{
1116 for (; low != high; ++low)
Sean Hunt6f0342c2011-07-09 03:40:04 +00001117 {
1118#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001119 if (!iswctype_l(*low, m, __l))
1120 break;
Sean Hunt6f0342c2011-07-09 03:40:04 +00001121#else
1122 if (m & space && iswspace_l(*low, __l)) continue;
1123 if (m & print && iswprint_l(*low, __l)) continue;
1124 if (m & cntrl && iswcntrl_l(*low, __l)) continue;
1125 if (m & upper && iswupper_l(*low, __l)) continue;
1126 if (m & lower && iswlower_l(*low, __l)) continue;
1127 if (m & alpha && iswalpha_l(*low, __l)) continue;
1128 if (m & digit && iswdigit_l(*low, __l)) continue;
1129 if (m & punct && iswpunct_l(*low, __l)) continue;
1130 if (m & xdigit && iswxdigit_l(*low, __l)) continue;
1131 if (m & blank && iswblank_l(*low, __l)) continue;
1132 break;
1133#endif
1134 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001135 return low;
1136}
1137
1138wchar_t
1139ctype_byname<wchar_t>::do_toupper(char_type c) const
1140{
1141 return towupper_l(c, __l);
1142}
1143
1144const wchar_t*
1145ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1146{
1147 for (; low != high; ++low)
1148 *low = towupper_l(*low, __l);
1149 return low;
1150}
1151
1152wchar_t
1153ctype_byname<wchar_t>::do_tolower(char_type c) const
1154{
1155 return towlower_l(c, __l);
1156}
1157
1158const wchar_t*
1159ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1160{
1161 for (; low != high; ++low)
1162 *low = towlower_l(*low, __l);
1163 return low;
1164}
1165
1166wchar_t
1167ctype_byname<wchar_t>::do_widen(char c) const
1168{
Sean Huntf3907e62011-07-15 05:40:33 +00001169#ifdef _LIBCPP_STABLE_APPLE_ABI
1170 return btowc_l(c, __l);
1171#else
1172 return __btowc_l(c, __l);
1173#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001174}
1175
1176const char*
1177ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1178{
1179 for (; low != high; ++low, ++dest)
Sean Huntf3907e62011-07-15 05:40:33 +00001180#ifdef _LIBCPP_STABLE_APPLE_ABI
1181 *dest = btowc_l(*low, __l);
1182#else
1183 *dest = __btowc_l(*low, __l);
1184#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001185 return low;
1186}
1187
1188char
1189ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1190{
Sean Huntf3907e62011-07-15 05:40:33 +00001191#ifdef _LIBCPP_STABLE_APPLE_ABI
1192 int r = wctob_l(c, __l);
1193#else
1194 int r = __wctob_l(c, __l);
1195#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001196 return r != WEOF ? static_cast<char>(r) : dfault;
1197}
1198
1199const wchar_t*
1200ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1201{
1202 for (; low != high; ++low, ++dest)
1203 {
Sean Huntf3907e62011-07-15 05:40:33 +00001204#ifdef _LIBCPP_STABLE_APPLE_ABI
1205 int r = wctob_l(*low, __l);
1206#else
1207 int r = __wctob_l(*low, __l);
1208#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001209 *dest = r != WEOF ? static_cast<char>(r) : dfault;
1210 }
1211 return low;
1212}
1213
1214// template <> class codecvt<char, char, mbstate_t>
1215
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001216locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001217
1218codecvt<char, char, mbstate_t>::~codecvt()
1219{
1220}
1221
1222codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001223codecvt<char, char, mbstate_t>::do_out(state_type&,
1224 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001225 extern_type* to, extern_type*, extern_type*& to_nxt) const
1226{
1227 frm_nxt = frm;
1228 to_nxt = to;
1229 return noconv;
1230}
1231
1232codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001233codecvt<char, char, mbstate_t>::do_in(state_type&,
1234 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001235 intern_type* to, intern_type*, intern_type*& to_nxt) const
1236{
1237 frm_nxt = frm;
1238 to_nxt = to;
1239 return noconv;
1240}
1241
1242codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001243codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001244 extern_type* to, extern_type*, extern_type*& to_nxt) const
1245{
1246 to_nxt = to;
1247 return noconv;
1248}
1249
1250int
Howard Hinnantc9834542011-05-31 15:34:58 +00001251codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001252{
1253 return 1;
1254}
1255
1256bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001257codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001258{
1259 return true;
1260}
1261
1262int
1263codecvt<char, char, mbstate_t>::do_length(state_type&,
1264 const extern_type* frm, const extern_type* end, size_t mx) const
1265{
1266 return static_cast<int>(min<size_t>(mx, end-frm));
1267}
1268
1269int
Howard Hinnantc9834542011-05-31 15:34:58 +00001270codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001271{
1272 return 1;
1273}
1274
1275// template <> class codecvt<wchar_t, char, mbstate_t>
1276
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001277locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001278
1279codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1280 : locale::facet(refs),
1281 __l(0)
1282{
1283}
1284
1285codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1286 : locale::facet(refs),
1287 __l(newlocale(LC_ALL_MASK, nm, 0))
1288{
Howard Hinnantd4444702010-08-11 17:04:31 +00001289#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001290 if (__l == 0)
1291 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1292 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001293#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001294}
1295
1296codecvt<wchar_t, char, mbstate_t>::~codecvt()
1297{
1298 if (__l != 0)
1299 freelocale(__l);
1300}
1301
1302codecvt<wchar_t, char, mbstate_t>::result
1303codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001304 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001305 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1306{
1307 // look for first internal null in frm
1308 const intern_type* fend = frm;
1309 for (; fend != frm_end; ++fend)
1310 if (*fend == 0)
1311 break;
1312 // loop over all null-terminated sequences in frm
1313 to_nxt = to;
1314 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1315 {
1316 // save state in case needed to reover to_nxt on error
1317 mbstate_t save_state = st;
Sean Huntf3907e62011-07-15 05:40:33 +00001318#ifdef _LIBCPP_STABLE_APPLE_ABI
1319 size_t n = wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1320#else
1321 size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1322#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001323 if (n == size_t(-1))
1324 {
1325 // need to recover to_nxt
1326 for (to_nxt = to; frm != frm_nxt; ++frm)
1327 {
Sean Huntf3907e62011-07-15 05:40:33 +00001328#ifdef _LIBCPP_STABLE_APPLE_ABI
1329 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1330#else
1331 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1332#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001333 if (n == size_t(-1))
1334 break;
1335 to_nxt += n;
1336 }
1337 frm_nxt = frm;
1338 return error;
1339 }
1340 if (n == 0)
1341 return partial;
1342 to_nxt += n;
1343 if (to_nxt == to_end)
1344 break;
1345 if (fend != frm_end) // set up next null terminated sequence
1346 {
1347 // Try to write the terminating null
1348 extern_type tmp[MB_LEN_MAX];
Sean Huntf3907e62011-07-15 05:40:33 +00001349#ifdef _LIBCPP_STABLE_APPLE_ABI
1350 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1351#else
1352 n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1353#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354 if (n == size_t(-1)) // on error
1355 return error;
1356 if (n > to_end-to_nxt) // is there room?
1357 return partial;
1358 for (extern_type* p = tmp; n; --n) // write it
1359 *to_nxt++ = *p++;
1360 ++frm_nxt;
1361 // look for next null in frm
1362 for (fend = frm_nxt; fend != frm_end; ++fend)
1363 if (*fend == 0)
1364 break;
1365 }
1366 }
1367 return frm_nxt == frm_end ? ok : partial;
1368}
1369
1370codecvt<wchar_t, char, mbstate_t>::result
1371codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001372 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001373 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1374{
1375 // look for first internal null in frm
1376 const extern_type* fend = frm;
1377 for (; fend != frm_end; ++fend)
1378 if (*fend == 0)
1379 break;
1380 // loop over all null-terminated sequences in frm
1381 to_nxt = to;
1382 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1383 {
1384 // save state in case needed to reover to_nxt on error
1385 mbstate_t save_state = st;
Sean Huntf3907e62011-07-15 05:40:33 +00001386#ifdef _LIBCPP_STABLE_APPLE_ABI
1387 size_t n = mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1388#else
1389 size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1390#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001391 if (n == size_t(-1))
1392 {
1393 // need to recover to_nxt
1394 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1395 {
Sean Huntf3907e62011-07-15 05:40:33 +00001396#ifdef _LIBCPP_STABLE_APPLE_ABI
1397 n = mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1398#else
1399 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1400#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001401 switch (n)
1402 {
1403 case 0:
1404 ++frm;
1405 break;
1406 case -1:
1407 frm_nxt = frm;
1408 return error;
1409 case -2:
1410 frm_nxt = frm;
1411 return partial;
1412 default:
1413 frm += n;
1414 break;
1415 }
1416 }
1417 frm_nxt = frm;
1418 return frm_nxt == frm_end ? ok : partial;
1419 }
1420 if (n == 0)
1421 return error;
1422 to_nxt += n;
1423 if (to_nxt == to_end)
1424 break;
1425 if (fend != frm_end) // set up next null terminated sequence
1426 {
1427 // Try to write the terminating null
Sean Huntf3907e62011-07-15 05:40:33 +00001428#ifdef _LIBCPP_STABLE_APPLE_ABI
1429 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1430#else
1431 n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1432#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001433 if (n != 0) // on error
1434 return error;
1435 ++to_nxt;
1436 ++frm_nxt;
1437 // look for next null in frm
1438 for (fend = frm_nxt; fend != frm_end; ++fend)
1439 if (*fend == 0)
1440 break;
1441 }
1442 }
1443 return frm_nxt == frm_end ? ok : partial;
1444}
1445
1446codecvt<wchar_t, char, mbstate_t>::result
1447codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1448 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1449{
1450 to_nxt = to;
1451 extern_type tmp[MB_LEN_MAX];
Sean Huntf3907e62011-07-15 05:40:33 +00001452#ifdef _LIBCPP_STABLE_APPLE_ABI
1453 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1454#else
1455 size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1456#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001457 if (n == size_t(-1) || n == 0) // on error
1458 return error;
1459 --n;
1460 if (n > to_end-to_nxt) // is there room?
1461 return partial;
1462 for (extern_type* p = tmp; n; --n) // write it
1463 *to_nxt++ = *p++;
1464 return ok;
1465}
1466
1467int
Howard Hinnantc9834542011-05-31 15:34:58 +00001468codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001469{
Sean Huntf3907e62011-07-15 05:40:33 +00001470#ifdef _LIBCPP_STABLE_APPLE_ABI
1471 if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1472#else
1473 if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1474#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475 {
1476 // stateless encoding
Sean Huntf3907e62011-07-15 05:40:33 +00001477#ifdef _LIBCPP_STABLE_APPLE_ABI
1478 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1479#else
1480 if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1481#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001482 return 1; // which take more than 1 char to form a wchar_t
1483 return 0;
1484 }
1485 return -1;
1486}
1487
1488bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001489codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001490{
1491 return false;
1492}
1493
1494int
1495codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1496 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1497{
1498 int nbytes = 0;
1499 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1500 {
Sean Huntf3907e62011-07-15 05:40:33 +00001501#ifdef _LIBCPP_STABLE_APPLE_ABI
1502 size_t n = mbrlen_l(frm, frm_end-frm, &st, __l);
1503#else
1504 size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1505#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001506 switch (n)
1507 {
1508 case 0:
1509 ++nbytes;
1510 ++frm;
1511 break;
1512 case -1:
1513 case -2:
1514 return nbytes;
1515 default:
1516 nbytes += n;
1517 frm += n;
1518 break;
1519 }
1520 }
1521 return nbytes;
1522}
1523
1524int
Howard Hinnantc9834542011-05-31 15:34:58 +00001525codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001526{
Sean Huntf3907e62011-07-15 05:40:33 +00001527#ifdef _LIBCPP_STABLE_APPLE_ABI
1528 return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
1529#else
1530 return __l == 0 ? 1 : __mb_cur_max_l(__l);
1531#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001532}
1533
1534// Valid UTF ranges
1535// UTF-32 UTF-16 UTF-8 # of code points
1536// first second first second third fourth
1537// 000000 - 00007F 0000 - 007F 00 - 7F 127
1538// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1539// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1540// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1541// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1542// 00D800 - 00DFFF invalid
1543// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1544// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1545// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1546// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1547
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00001548static
1549codecvt_base::result
1550utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1551 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1552 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1553{
1554 frm_nxt = frm;
1555 to_nxt = to;
1556 if (mode & generate_header)
1557 {
1558 if (to_end-to_nxt < 3)
1559 return codecvt_base::partial;
1560 *to_nxt++ = static_cast<uint8_t>(0xEF);
1561 *to_nxt++ = static_cast<uint8_t>(0xBB);
1562 *to_nxt++ = static_cast<uint8_t>(0xBF);
1563 }
1564 for (; frm_nxt < frm_end; ++frm_nxt)
1565 {
1566 uint16_t wc1 = *frm_nxt;
1567 if (wc1 > Maxcode)
1568 return codecvt_base::error;
1569 if (wc1 < 0x0080)
1570 {
1571 if (to_end-to_nxt < 1)
1572 return codecvt_base::partial;
1573 *to_nxt++ = static_cast<uint8_t>(wc1);
1574 }
1575 else if (wc1 < 0x0800)
1576 {
1577 if (to_end-to_nxt < 2)
1578 return codecvt_base::partial;
1579 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1580 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1581 }
1582 else if (wc1 < 0xD800)
1583 {
1584 if (to_end-to_nxt < 3)
1585 return codecvt_base::partial;
1586 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1587 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1588 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1589 }
1590 else if (wc1 < 0xDC00)
1591 {
1592 if (frm_end-frm_nxt < 2)
1593 return codecvt_base::partial;
1594 uint16_t wc2 = frm_nxt[1];
1595 if ((wc2 & 0xFC00) != 0xDC00)
1596 return codecvt_base::error;
1597 if (to_end-to_nxt < 4)
1598 return codecvt_base::partial;
1599 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1600 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1601 return codecvt_base::error;
1602 ++frm_nxt;
1603 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1604 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1605 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1606 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1607 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1608 }
1609 else if (wc1 < 0xE000)
1610 {
1611 return codecvt_base::error;
1612 }
1613 else
1614 {
1615 if (to_end-to_nxt < 3)
1616 return codecvt_base::partial;
1617 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1618 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1619 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1620 }
1621 }
1622 return codecvt_base::ok;
1623}
1624
1625static
1626codecvt_base::result
1627utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1628 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1629 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1630{
1631 frm_nxt = frm;
1632 to_nxt = to;
1633 if (mode & generate_header)
1634 {
1635 if (to_end-to_nxt < 3)
1636 return codecvt_base::partial;
1637 *to_nxt++ = static_cast<uint8_t>(0xEF);
1638 *to_nxt++ = static_cast<uint8_t>(0xBB);
1639 *to_nxt++ = static_cast<uint8_t>(0xBF);
1640 }
1641 for (; frm_nxt < frm_end; ++frm_nxt)
1642 {
1643 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1644 if (wc1 > Maxcode)
1645 return codecvt_base::error;
1646 if (wc1 < 0x0080)
1647 {
1648 if (to_end-to_nxt < 1)
1649 return codecvt_base::partial;
1650 *to_nxt++ = static_cast<uint8_t>(wc1);
1651 }
1652 else if (wc1 < 0x0800)
1653 {
1654 if (to_end-to_nxt < 2)
1655 return codecvt_base::partial;
1656 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1657 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1658 }
1659 else if (wc1 < 0xD800)
1660 {
1661 if (to_end-to_nxt < 3)
1662 return codecvt_base::partial;
1663 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1664 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1665 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1666 }
1667 else if (wc1 < 0xDC00)
1668 {
1669 if (frm_end-frm_nxt < 2)
1670 return codecvt_base::partial;
1671 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1672 if ((wc2 & 0xFC00) != 0xDC00)
1673 return codecvt_base::error;
1674 if (to_end-to_nxt < 4)
1675 return codecvt_base::partial;
1676 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1677 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1678 return codecvt_base::error;
1679 ++frm_nxt;
1680 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1681 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1682 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1683 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1684 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1685 }
1686 else if (wc1 < 0xE000)
1687 {
1688 return codecvt_base::error;
1689 }
1690 else
1691 {
1692 if (to_end-to_nxt < 3)
1693 return codecvt_base::partial;
1694 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1695 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1696 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1697 }
1698 }
1699 return codecvt_base::ok;
1700}
1701
1702static
1703codecvt_base::result
1704utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1705 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1706 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1707{
1708 frm_nxt = frm;
1709 to_nxt = to;
1710 if (mode & consume_header)
1711 {
1712 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1713 frm_nxt[2] == 0xBF)
1714 frm_nxt += 3;
1715 }
1716 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1717 {
1718 uint8_t c1 = *frm_nxt;
1719 if (c1 > Maxcode)
1720 return codecvt_base::error;
1721 if (c1 < 0x80)
1722 {
1723 *to_nxt = static_cast<uint16_t>(c1);
1724 ++frm_nxt;
1725 }
1726 else if (c1 < 0xC2)
1727 {
1728 return codecvt_base::error;
1729 }
1730 else if (c1 < 0xE0)
1731 {
1732 if (frm_end-frm_nxt < 2)
1733 return codecvt_base::partial;
1734 uint8_t c2 = frm_nxt[1];
1735 if ((c2 & 0xC0) != 0x80)
1736 return codecvt_base::error;
1737 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1738 if (t > Maxcode)
1739 return codecvt_base::error;
1740 *to_nxt = t;
1741 frm_nxt += 2;
1742 }
1743 else if (c1 < 0xF0)
1744 {
1745 if (frm_end-frm_nxt < 3)
1746 return codecvt_base::partial;
1747 uint8_t c2 = frm_nxt[1];
1748 uint8_t c3 = frm_nxt[2];
1749 switch (c1)
1750 {
1751 case 0xE0:
1752 if ((c2 & 0xE0) != 0xA0)
1753 return codecvt_base::error;
1754 break;
1755 case 0xED:
1756 if ((c2 & 0xE0) != 0x80)
1757 return codecvt_base::error;
1758 break;
1759 default:
1760 if ((c2 & 0xC0) != 0x80)
1761 return codecvt_base::error;
1762 break;
1763 }
1764 if ((c3 & 0xC0) != 0x80)
1765 return codecvt_base::error;
1766 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1767 | ((c2 & 0x3F) << 6)
1768 | (c3 & 0x3F));
1769 if (t > Maxcode)
1770 return codecvt_base::error;
1771 *to_nxt = t;
1772 frm_nxt += 3;
1773 }
1774 else if (c1 < 0xF5)
1775 {
1776 if (frm_end-frm_nxt < 4)
1777 return codecvt_base::partial;
1778 uint8_t c2 = frm_nxt[1];
1779 uint8_t c3 = frm_nxt[2];
1780 uint8_t c4 = frm_nxt[3];
1781 switch (c1)
1782 {
1783 case 0xF0:
1784 if (!(0x90 <= c2 && c2 <= 0xBF))
1785 return codecvt_base::error;
1786 break;
1787 case 0xF4:
1788 if ((c2 & 0xF0) != 0x80)
1789 return codecvt_base::error;
1790 break;
1791 default:
1792 if ((c2 & 0xC0) != 0x80)
1793 return codecvt_base::error;
1794 break;
1795 }
1796 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1797 return codecvt_base::error;
1798 if (to_end-to_nxt < 2)
1799 return codecvt_base::partial;
1800 if (((((unsigned long)c1 & 7) << 18) +
1801 (((unsigned long)c2 & 0x3F) << 12) +
1802 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1803 return codecvt_base::error;
1804 *to_nxt = static_cast<uint16_t>(
1805 0xD800
1806 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1807 | ((c2 & 0x0F) << 2)
1808 | ((c3 & 0x30) >> 4));
1809 *++to_nxt = static_cast<uint16_t>(
1810 0xDC00
1811 | ((c3 & 0x0F) << 6)
1812 | (c4 & 0x3F));
1813 frm_nxt += 4;
1814 }
1815 else
1816 {
1817 return codecvt_base::error;
1818 }
1819 }
1820 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1821}
1822
1823static
1824codecvt_base::result
1825utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1826 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1827 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1828{
1829 frm_nxt = frm;
1830 to_nxt = to;
1831 if (mode & consume_header)
1832 {
1833 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1834 frm_nxt[2] == 0xBF)
1835 frm_nxt += 3;
1836 }
1837 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1838 {
1839 uint8_t c1 = *frm_nxt;
1840 if (c1 > Maxcode)
1841 return codecvt_base::error;
1842 if (c1 < 0x80)
1843 {
1844 *to_nxt = static_cast<uint32_t>(c1);
1845 ++frm_nxt;
1846 }
1847 else if (c1 < 0xC2)
1848 {
1849 return codecvt_base::error;
1850 }
1851 else if (c1 < 0xE0)
1852 {
1853 if (frm_end-frm_nxt < 2)
1854 return codecvt_base::partial;
1855 uint8_t c2 = frm_nxt[1];
1856 if ((c2 & 0xC0) != 0x80)
1857 return codecvt_base::error;
1858 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1859 if (t > Maxcode)
1860 return codecvt_base::error;
1861 *to_nxt = static_cast<uint32_t>(t);
1862 frm_nxt += 2;
1863 }
1864 else if (c1 < 0xF0)
1865 {
1866 if (frm_end-frm_nxt < 3)
1867 return codecvt_base::partial;
1868 uint8_t c2 = frm_nxt[1];
1869 uint8_t c3 = frm_nxt[2];
1870 switch (c1)
1871 {
1872 case 0xE0:
1873 if ((c2 & 0xE0) != 0xA0)
1874 return codecvt_base::error;
1875 break;
1876 case 0xED:
1877 if ((c2 & 0xE0) != 0x80)
1878 return codecvt_base::error;
1879 break;
1880 default:
1881 if ((c2 & 0xC0) != 0x80)
1882 return codecvt_base::error;
1883 break;
1884 }
1885 if ((c3 & 0xC0) != 0x80)
1886 return codecvt_base::error;
1887 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1888 | ((c2 & 0x3F) << 6)
1889 | (c3 & 0x3F));
1890 if (t > Maxcode)
1891 return codecvt_base::error;
1892 *to_nxt = static_cast<uint32_t>(t);
1893 frm_nxt += 3;
1894 }
1895 else if (c1 < 0xF5)
1896 {
1897 if (frm_end-frm_nxt < 4)
1898 return codecvt_base::partial;
1899 uint8_t c2 = frm_nxt[1];
1900 uint8_t c3 = frm_nxt[2];
1901 uint8_t c4 = frm_nxt[3];
1902 switch (c1)
1903 {
1904 case 0xF0:
1905 if (!(0x90 <= c2 && c2 <= 0xBF))
1906 return codecvt_base::error;
1907 break;
1908 case 0xF4:
1909 if ((c2 & 0xF0) != 0x80)
1910 return codecvt_base::error;
1911 break;
1912 default:
1913 if ((c2 & 0xC0) != 0x80)
1914 return codecvt_base::error;
1915 break;
1916 }
1917 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1918 return codecvt_base::error;
1919 if (to_end-to_nxt < 2)
1920 return codecvt_base::partial;
1921 if (((((unsigned long)c1 & 7) << 18) +
1922 (((unsigned long)c2 & 0x3F) << 12) +
1923 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1924 return codecvt_base::error;
1925 *to_nxt = static_cast<uint32_t>(
1926 0xD800
1927 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1928 | ((c2 & 0x0F) << 2)
1929 | ((c3 & 0x30) >> 4));
1930 *++to_nxt = static_cast<uint32_t>(
1931 0xDC00
1932 | ((c3 & 0x0F) << 6)
1933 | (c4 & 0x3F));
1934 frm_nxt += 4;
1935 }
1936 else
1937 {
1938 return codecvt_base::error;
1939 }
1940 }
1941 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1942}
1943
1944static
1945int
1946utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1947 size_t mx, unsigned long Maxcode = 0x10FFFF,
1948 codecvt_mode mode = codecvt_mode(0))
1949{
1950 const uint8_t* frm_nxt = frm;
1951 if (mode & consume_header)
1952 {
1953 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1954 frm_nxt[2] == 0xBF)
1955 frm_nxt += 3;
1956 }
1957 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1958 {
1959 uint8_t c1 = *frm_nxt;
1960 if (c1 > Maxcode)
1961 break;
1962 if (c1 < 0x80)
1963 {
1964 ++frm_nxt;
1965 }
1966 else if (c1 < 0xC2)
1967 {
1968 break;
1969 }
1970 else if (c1 < 0xE0)
1971 {
1972 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1973 break;
1974 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1975 if (t > Maxcode)
1976 break;
1977 frm_nxt += 2;
1978 }
1979 else if (c1 < 0xF0)
1980 {
1981 if (frm_end-frm_nxt < 3)
1982 break;
1983 uint8_t c2 = frm_nxt[1];
1984 uint8_t c3 = frm_nxt[2];
1985 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1986 | ((c2 & 0x3F) << 6)
1987 | (c3 & 0x3F));
1988 switch (c1)
1989 {
1990 case 0xE0:
1991 if ((c2 & 0xE0) != 0xA0)
1992 return static_cast<int>(frm_nxt - frm);
1993 break;
1994 case 0xED:
1995 if ((c2 & 0xE0) != 0x80)
1996 return static_cast<int>(frm_nxt - frm);
1997 break;
1998 default:
1999 if ((c2 & 0xC0) != 0x80)
2000 return static_cast<int>(frm_nxt - frm);
2001 break;
2002 }
2003 if ((c3 & 0xC0) != 0x80)
2004 break;
2005 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2006 break;
2007 frm_nxt += 3;
2008 }
2009 else if (c1 < 0xF5)
2010 {
2011 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2012 break;
2013 uint8_t c2 = frm_nxt[1];
2014 uint8_t c3 = frm_nxt[2];
2015 uint8_t c4 = frm_nxt[3];
2016 switch (c1)
2017 {
2018 case 0xF0:
2019 if (!(0x90 <= c2 && c2 <= 0xBF))
2020 return static_cast<int>(frm_nxt - frm);
2021 break;
2022 case 0xF4:
2023 if ((c2 & 0xF0) != 0x80)
2024 return static_cast<int>(frm_nxt - frm);
2025 break;
2026 default:
2027 if ((c2 & 0xC0) != 0x80)
2028 return static_cast<int>(frm_nxt - frm);
2029 break;
2030 }
2031 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2032 break;
2033 if (((((unsigned long)c1 & 7) << 18) +
2034 (((unsigned long)c2 & 0x3F) << 12) +
2035 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
2036 break;
2037 ++nchar16_t;
2038 frm_nxt += 4;
2039 }
2040 else
2041 {
2042 break;
2043 }
2044 }
2045 return static_cast<int>(frm_nxt - frm);
2046}
2047
2048static
2049codecvt_base::result
2050ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2051 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2052 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2053{
2054 frm_nxt = frm;
2055 to_nxt = to;
2056 if (mode & generate_header)
2057 {
2058 if (to_end-to_nxt < 3)
2059 return codecvt_base::partial;
2060 *to_nxt++ = static_cast<uint8_t>(0xEF);
2061 *to_nxt++ = static_cast<uint8_t>(0xBB);
2062 *to_nxt++ = static_cast<uint8_t>(0xBF);
2063 }
2064 for (; frm_nxt < frm_end; ++frm_nxt)
2065 {
2066 uint32_t wc = *frm_nxt;
2067 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2068 return codecvt_base::error;
2069 if (wc < 0x000080)
2070 {
2071 if (to_end-to_nxt < 1)
2072 return codecvt_base::partial;
2073 *to_nxt++ = static_cast<uint8_t>(wc);
2074 }
2075 else if (wc < 0x000800)
2076 {
2077 if (to_end-to_nxt < 2)
2078 return codecvt_base::partial;
2079 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2080 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2081 }
2082 else if (wc < 0x010000)
2083 {
2084 if (to_end-to_nxt < 3)
2085 return codecvt_base::partial;
2086 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2087 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2088 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2089 }
2090 else // if (wc < 0x110000)
2091 {
2092 if (to_end-to_nxt < 4)
2093 return codecvt_base::partial;
2094 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2095 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2096 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2097 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2098 }
2099 }
2100 return codecvt_base::ok;
2101}
2102
2103static
2104codecvt_base::result
2105utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2106 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2107 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2108{
2109 frm_nxt = frm;
2110 to_nxt = to;
2111 if (mode & consume_header)
2112 {
2113 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2114 frm_nxt[2] == 0xBF)
2115 frm_nxt += 3;
2116 }
2117 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2118 {
2119 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2120 if (c1 < 0x80)
2121 {
2122 if (c1 > Maxcode)
2123 return codecvt_base::error;
2124 *to_nxt = static_cast<uint32_t>(c1);
2125 ++frm_nxt;
2126 }
2127 else if (c1 < 0xC2)
2128 {
2129 return codecvt_base::error;
2130 }
2131 else if (c1 < 0xE0)
2132 {
2133 if (frm_end-frm_nxt < 2)
2134 return codecvt_base::partial;
2135 uint8_t c2 = frm_nxt[1];
2136 if ((c2 & 0xC0) != 0x80)
2137 return codecvt_base::error;
2138 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2139 | (c2 & 0x3F));
2140 if (t > Maxcode)
2141 return codecvt_base::error;
2142 *to_nxt = t;
2143 frm_nxt += 2;
2144 }
2145 else if (c1 < 0xF0)
2146 {
2147 if (frm_end-frm_nxt < 3)
2148 return codecvt_base::partial;
2149 uint8_t c2 = frm_nxt[1];
2150 uint8_t c3 = frm_nxt[2];
2151 switch (c1)
2152 {
2153 case 0xE0:
2154 if ((c2 & 0xE0) != 0xA0)
2155 return codecvt_base::error;
2156 break;
2157 case 0xED:
2158 if ((c2 & 0xE0) != 0x80)
2159 return codecvt_base::error;
2160 break;
2161 default:
2162 if ((c2 & 0xC0) != 0x80)
2163 return codecvt_base::error;
2164 break;
2165 }
2166 if ((c3 & 0xC0) != 0x80)
2167 return codecvt_base::error;
2168 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2169 | ((c2 & 0x3F) << 6)
2170 | (c3 & 0x3F));
2171 if (t > Maxcode)
2172 return codecvt_base::error;
2173 *to_nxt = t;
2174 frm_nxt += 3;
2175 }
2176 else if (c1 < 0xF5)
2177 {
2178 if (frm_end-frm_nxt < 4)
2179 return codecvt_base::partial;
2180 uint8_t c2 = frm_nxt[1];
2181 uint8_t c3 = frm_nxt[2];
2182 uint8_t c4 = frm_nxt[3];
2183 switch (c1)
2184 {
2185 case 0xF0:
2186 if (!(0x90 <= c2 && c2 <= 0xBF))
2187 return codecvt_base::error;
2188 break;
2189 case 0xF4:
2190 if ((c2 & 0xF0) != 0x80)
2191 return codecvt_base::error;
2192 break;
2193 default:
2194 if ((c2 & 0xC0) != 0x80)
2195 return codecvt_base::error;
2196 break;
2197 }
2198 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2199 return codecvt_base::error;
2200 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2201 | ((c2 & 0x3F) << 12)
2202 | ((c3 & 0x3F) << 6)
2203 | (c4 & 0x3F));
2204 if (t > Maxcode)
2205 return codecvt_base::error;
2206 *to_nxt = t;
2207 frm_nxt += 4;
2208 }
2209 else
2210 {
2211 return codecvt_base::error;
2212 }
2213 }
2214 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2215}
2216
2217static
2218int
2219utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2220 size_t mx, unsigned long Maxcode = 0x10FFFF,
2221 codecvt_mode mode = codecvt_mode(0))
2222{
2223 const uint8_t* frm_nxt = frm;
2224 if (mode & consume_header)
2225 {
2226 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2227 frm_nxt[2] == 0xBF)
2228 frm_nxt += 3;
2229 }
2230 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2231 {
2232 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2233 if (c1 < 0x80)
2234 {
2235 if (c1 > Maxcode)
2236 break;
2237 ++frm_nxt;
2238 }
2239 else if (c1 < 0xC2)
2240 {
2241 break;
2242 }
2243 else if (c1 < 0xE0)
2244 {
2245 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2246 break;
2247 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2248 break;
2249 frm_nxt += 2;
2250 }
2251 else if (c1 < 0xF0)
2252 {
2253 if (frm_end-frm_nxt < 3)
2254 break;
2255 uint8_t c2 = frm_nxt[1];
2256 uint8_t c3 = frm_nxt[2];
2257 switch (c1)
2258 {
2259 case 0xE0:
2260 if ((c2 & 0xE0) != 0xA0)
2261 return static_cast<int>(frm_nxt - frm);
2262 break;
2263 case 0xED:
2264 if ((c2 & 0xE0) != 0x80)
2265 return static_cast<int>(frm_nxt - frm);
2266 break;
2267 default:
2268 if ((c2 & 0xC0) != 0x80)
2269 return static_cast<int>(frm_nxt - frm);
2270 break;
2271 }
2272 if ((c3 & 0xC0) != 0x80)
2273 break;
2274 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2275 break;
2276 frm_nxt += 3;
2277 }
2278 else if (c1 < 0xF5)
2279 {
2280 if (frm_end-frm_nxt < 4)
2281 break;
2282 uint8_t c2 = frm_nxt[1];
2283 uint8_t c3 = frm_nxt[2];
2284 uint8_t c4 = frm_nxt[3];
2285 switch (c1)
2286 {
2287 case 0xF0:
2288 if (!(0x90 <= c2 && c2 <= 0xBF))
2289 return static_cast<int>(frm_nxt - frm);
2290 break;
2291 case 0xF4:
2292 if ((c2 & 0xF0) != 0x80)
2293 return static_cast<int>(frm_nxt - frm);
2294 break;
2295 default:
2296 if ((c2 & 0xC0) != 0x80)
2297 return static_cast<int>(frm_nxt - frm);
2298 break;
2299 }
2300 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2301 break;
2302 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2303 | ((c2 & 0x3F) << 12)
2304 | ((c3 & 0x3F) << 6)
2305 | (c4 & 0x3F));
2306 if ((((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
2307 ((c3 & 0x3F) << 6) | (c4 & 0x3F)) > Maxcode)
2308 break;
2309 frm_nxt += 4;
2310 }
2311 else
2312 {
2313 break;
2314 }
2315 }
2316 return static_cast<int>(frm_nxt - frm);
2317}
2318
2319static
2320codecvt_base::result
2321ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2322 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2323 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2324{
2325 frm_nxt = frm;
2326 to_nxt = to;
2327 if (mode & generate_header)
2328 {
2329 if (to_end-to_nxt < 3)
2330 return codecvt_base::partial;
2331 *to_nxt++ = static_cast<uint8_t>(0xEF);
2332 *to_nxt++ = static_cast<uint8_t>(0xBB);
2333 *to_nxt++ = static_cast<uint8_t>(0xBF);
2334 }
2335 for (; frm_nxt < frm_end; ++frm_nxt)
2336 {
2337 uint16_t wc = *frm_nxt;
2338 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2339 return codecvt_base::error;
2340 if (wc < 0x0080)
2341 {
2342 if (to_end-to_nxt < 1)
2343 return codecvt_base::partial;
2344 *to_nxt++ = static_cast<uint8_t>(wc);
2345 }
2346 else if (wc < 0x0800)
2347 {
2348 if (to_end-to_nxt < 2)
2349 return codecvt_base::partial;
2350 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2351 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2352 }
2353 else // if (wc <= 0xFFFF)
2354 {
2355 if (to_end-to_nxt < 3)
2356 return codecvt_base::partial;
2357 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2358 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2359 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2360 }
2361 }
2362 return codecvt_base::ok;
2363}
2364
2365static
2366codecvt_base::result
2367utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2368 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2369 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2370{
2371 frm_nxt = frm;
2372 to_nxt = to;
2373 if (mode & consume_header)
2374 {
2375 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2376 frm_nxt[2] == 0xBF)
2377 frm_nxt += 3;
2378 }
2379 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2380 {
2381 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2382 if (c1 < 0x80)
2383 {
2384 if (c1 > Maxcode)
2385 return codecvt_base::error;
2386 *to_nxt = static_cast<uint16_t>(c1);
2387 ++frm_nxt;
2388 }
2389 else if (c1 < 0xC2)
2390 {
2391 return codecvt_base::error;
2392 }
2393 else if (c1 < 0xE0)
2394 {
2395 if (frm_end-frm_nxt < 2)
2396 return codecvt_base::partial;
2397 uint8_t c2 = frm_nxt[1];
2398 if ((c2 & 0xC0) != 0x80)
2399 return codecvt_base::error;
2400 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2401 | (c2 & 0x3F));
2402 if (t > Maxcode)
2403 return codecvt_base::error;
2404 *to_nxt = t;
2405 frm_nxt += 2;
2406 }
2407 else if (c1 < 0xF0)
2408 {
2409 if (frm_end-frm_nxt < 3)
2410 return codecvt_base::partial;
2411 uint8_t c2 = frm_nxt[1];
2412 uint8_t c3 = frm_nxt[2];
2413 switch (c1)
2414 {
2415 case 0xE0:
2416 if ((c2 & 0xE0) != 0xA0)
2417 return codecvt_base::error;
2418 break;
2419 case 0xED:
2420 if ((c2 & 0xE0) != 0x80)
2421 return codecvt_base::error;
2422 break;
2423 default:
2424 if ((c2 & 0xC0) != 0x80)
2425 return codecvt_base::error;
2426 break;
2427 }
2428 if ((c3 & 0xC0) != 0x80)
2429 return codecvt_base::error;
2430 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2431 | ((c2 & 0x3F) << 6)
2432 | (c3 & 0x3F));
2433 if (t > Maxcode)
2434 return codecvt_base::error;
2435 *to_nxt = t;
2436 frm_nxt += 3;
2437 }
2438 else
2439 {
2440 return codecvt_base::error;
2441 }
2442 }
2443 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2444}
2445
2446static
2447int
2448utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2449 size_t mx, unsigned long Maxcode = 0x10FFFF,
2450 codecvt_mode mode = codecvt_mode(0))
2451{
2452 const uint8_t* frm_nxt = frm;
2453 if (mode & consume_header)
2454 {
2455 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2456 frm_nxt[2] == 0xBF)
2457 frm_nxt += 3;
2458 }
2459 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2460 {
2461 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2462 if (c1 < 0x80)
2463 {
2464 if (c1 > Maxcode)
2465 break;
2466 ++frm_nxt;
2467 }
2468 else if (c1 < 0xC2)
2469 {
2470 break;
2471 }
2472 else if (c1 < 0xE0)
2473 {
2474 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2475 break;
2476 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2477 break;
2478 frm_nxt += 2;
2479 }
2480 else if (c1 < 0xF0)
2481 {
2482 if (frm_end-frm_nxt < 3)
2483 break;
2484 uint8_t c2 = frm_nxt[1];
2485 uint8_t c3 = frm_nxt[2];
2486 switch (c1)
2487 {
2488 case 0xE0:
2489 if ((c2 & 0xE0) != 0xA0)
2490 return static_cast<int>(frm_nxt - frm);
2491 break;
2492 case 0xED:
2493 if ((c2 & 0xE0) != 0x80)
2494 return static_cast<int>(frm_nxt - frm);
2495 break;
2496 default:
2497 if ((c2 & 0xC0) != 0x80)
2498 return static_cast<int>(frm_nxt - frm);
2499 break;
2500 }
2501 if ((c3 & 0xC0) != 0x80)
2502 break;
2503 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2504 break;
2505 frm_nxt += 3;
2506 }
2507 else
2508 {
2509 break;
2510 }
2511 }
2512 return static_cast<int>(frm_nxt - frm);
2513}
2514
2515static
2516codecvt_base::result
2517ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2518 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2519 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2520{
2521 frm_nxt = frm;
2522 to_nxt = to;
2523 if (mode & generate_header)
2524 {
2525 if (to_end-to_nxt < 2)
2526 return codecvt_base::partial;
2527 *to_nxt++ = static_cast<uint8_t>(0xFE);
2528 *to_nxt++ = static_cast<uint8_t>(0xFF);
2529 }
2530 for (; frm_nxt < frm_end; ++frm_nxt)
2531 {
2532 uint32_t wc = *frm_nxt;
2533 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2534 return codecvt_base::error;
2535 if (wc < 0x010000)
2536 {
2537 if (to_end-to_nxt < 2)
2538 return codecvt_base::partial;
2539 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2540 *to_nxt++ = static_cast<uint8_t>(wc);
2541 }
2542 else
2543 {
2544 if (to_end-to_nxt < 4)
2545 return codecvt_base::partial;
2546 uint16_t t = static_cast<uint16_t>(
2547 0xD800
2548 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2549 | ((wc & 0x00FC00) >> 10));
2550 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2551 *to_nxt++ = static_cast<uint8_t>(t);
2552 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2553 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2554 *to_nxt++ = static_cast<uint8_t>(t);
2555 }
2556 }
2557 return codecvt_base::ok;
2558}
2559
2560static
2561codecvt_base::result
2562utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2563 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2564 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2565{
2566 frm_nxt = frm;
2567 to_nxt = to;
2568 if (mode & consume_header)
2569 {
2570 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2571 frm_nxt += 2;
2572 }
2573 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2574 {
2575 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2576 if ((c1 & 0xFC00) == 0xDC00)
2577 return codecvt_base::error;
2578 if ((c1 & 0xFC00) != 0xD800)
2579 {
2580 if (c1 > Maxcode)
2581 return codecvt_base::error;
2582 *to_nxt = static_cast<uint32_t>(c1);
2583 frm_nxt += 2;
2584 }
2585 else
2586 {
2587 if (frm_end-frm_nxt < 4)
2588 return codecvt_base::partial;
2589 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2590 if ((c2 & 0xFC00) != 0xDC00)
2591 return codecvt_base::error;
2592 uint32_t t = static_cast<uint32_t>(
2593 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2594 | ((c1 & 0x003F) << 10)
2595 | (c2 & 0x03FF));
2596 if (t > Maxcode)
2597 return codecvt_base::error;
2598 *to_nxt = t;
2599 frm_nxt += 4;
2600 }
2601 }
2602 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2603}
2604
2605static
2606int
2607utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2608 size_t mx, unsigned long Maxcode = 0x10FFFF,
2609 codecvt_mode mode = codecvt_mode(0))
2610{
2611 const uint8_t* frm_nxt = frm;
2612 frm_nxt = frm;
2613 if (mode & consume_header)
2614 {
2615 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2616 frm_nxt += 2;
2617 }
2618 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2619 {
2620 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2621 if ((c1 & 0xFC00) == 0xDC00)
2622 break;
2623 if ((c1 & 0xFC00) != 0xD800)
2624 {
2625 if (c1 > Maxcode)
2626 break;
2627 frm_nxt += 2;
2628 }
2629 else
2630 {
2631 if (frm_end-frm_nxt < 4)
2632 break;
2633 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2634 if ((c2 & 0xFC00) != 0xDC00)
2635 break;
2636 uint32_t t = static_cast<uint32_t>(
2637 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2638 | ((c1 & 0x003F) << 10)
2639 | (c2 & 0x03FF));
2640 if (t > Maxcode)
2641 break;
2642 frm_nxt += 4;
2643 }
2644 }
2645 return static_cast<int>(frm_nxt - frm);
2646}
2647
2648static
2649codecvt_base::result
2650ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2651 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2652 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2653{
2654 frm_nxt = frm;
2655 to_nxt = to;
2656 if (mode & generate_header)
2657 {
2658 if (to_end-to_nxt < 2)
2659 return codecvt_base::partial;
2660 *to_nxt++ = static_cast<uint8_t>(0xFF);
2661 *to_nxt++ = static_cast<uint8_t>(0xFE);
2662 }
2663 for (; frm_nxt < frm_end; ++frm_nxt)
2664 {
2665 uint32_t wc = *frm_nxt;
2666 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2667 return codecvt_base::error;
2668 if (wc < 0x010000)
2669 {
2670 if (to_end-to_nxt < 2)
2671 return codecvt_base::partial;
2672 *to_nxt++ = static_cast<uint8_t>(wc);
2673 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2674 }
2675 else
2676 {
2677 if (to_end-to_nxt < 4)
2678 return codecvt_base::partial;
2679 uint16_t t = static_cast<uint16_t>(
2680 0xD800
2681 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2682 | ((wc & 0x00FC00) >> 10));
2683 *to_nxt++ = static_cast<uint8_t>(t);
2684 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2685 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2686 *to_nxt++ = static_cast<uint8_t>(t);
2687 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2688 }
2689 }
2690 return codecvt_base::ok;
2691}
2692
2693static
2694codecvt_base::result
2695utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2696 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2697 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2698{
2699 frm_nxt = frm;
2700 to_nxt = to;
2701 if (mode & consume_header)
2702 {
2703 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2704 frm_nxt += 2;
2705 }
2706 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2707 {
2708 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2709 if ((c1 & 0xFC00) == 0xDC00)
2710 return codecvt_base::error;
2711 if ((c1 & 0xFC00) != 0xD800)
2712 {
2713 if (c1 > Maxcode)
2714 return codecvt_base::error;
2715 *to_nxt = static_cast<uint32_t>(c1);
2716 frm_nxt += 2;
2717 }
2718 else
2719 {
2720 if (frm_end-frm_nxt < 4)
2721 return codecvt_base::partial;
2722 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2723 if ((c2 & 0xFC00) != 0xDC00)
2724 return codecvt_base::error;
2725 uint32_t t = static_cast<uint32_t>(
2726 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2727 | ((c1 & 0x003F) << 10)
2728 | (c2 & 0x03FF));
2729 if (t > Maxcode)
2730 return codecvt_base::error;
2731 *to_nxt = t;
2732 frm_nxt += 4;
2733 }
2734 }
2735 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2736}
2737
2738static
2739int
2740utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2741 size_t mx, unsigned long Maxcode = 0x10FFFF,
2742 codecvt_mode mode = codecvt_mode(0))
2743{
2744 const uint8_t* frm_nxt = frm;
2745 frm_nxt = frm;
2746 if (mode & consume_header)
2747 {
2748 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2749 frm_nxt += 2;
2750 }
2751 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2752 {
2753 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2754 if ((c1 & 0xFC00) == 0xDC00)
2755 break;
2756 if ((c1 & 0xFC00) != 0xD800)
2757 {
2758 if (c1 > Maxcode)
2759 break;
2760 frm_nxt += 2;
2761 }
2762 else
2763 {
2764 if (frm_end-frm_nxt < 4)
2765 break;
2766 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2767 if ((c2 & 0xFC00) != 0xDC00)
2768 break;
2769 uint32_t t = static_cast<uint32_t>(
2770 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2771 | ((c1 & 0x003F) << 10)
2772 | (c2 & 0x03FF));
2773 if (t > Maxcode)
2774 break;
2775 frm_nxt += 4;
2776 }
2777 }
2778 return static_cast<int>(frm_nxt - frm);
2779}
2780
2781static
2782codecvt_base::result
2783ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2784 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2785 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2786{
2787 frm_nxt = frm;
2788 to_nxt = to;
2789 if (mode & generate_header)
2790 {
2791 if (to_end-to_nxt < 2)
2792 return codecvt_base::partial;
2793 *to_nxt++ = static_cast<uint8_t>(0xFE);
2794 *to_nxt++ = static_cast<uint8_t>(0xFF);
2795 }
2796 for (; frm_nxt < frm_end; ++frm_nxt)
2797 {
2798 uint16_t wc = *frm_nxt;
2799 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2800 return codecvt_base::error;
2801 if (to_end-to_nxt < 2)
2802 return codecvt_base::partial;
2803 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2804 *to_nxt++ = static_cast<uint8_t>(wc);
2805 }
2806 return codecvt_base::ok;
2807}
2808
2809static
2810codecvt_base::result
2811utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2812 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2813 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2814{
2815 frm_nxt = frm;
2816 to_nxt = to;
2817 if (mode & consume_header)
2818 {
2819 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2820 frm_nxt += 2;
2821 }
2822 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2823 {
2824 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2825 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2826 return codecvt_base::error;
2827 *to_nxt = c1;
2828 frm_nxt += 2;
2829 }
2830 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2831}
2832
2833static
2834int
2835utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2836 size_t mx, unsigned long Maxcode = 0x10FFFF,
2837 codecvt_mode mode = codecvt_mode(0))
2838{
2839 const uint8_t* frm_nxt = frm;
2840 frm_nxt = frm;
2841 if (mode & consume_header)
2842 {
2843 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2844 frm_nxt += 2;
2845 }
2846 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2847 {
2848 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2849 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2850 break;
2851 frm_nxt += 2;
2852 }
2853 return static_cast<int>(frm_nxt - frm);
2854}
2855
2856static
2857codecvt_base::result
2858ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2859 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2860 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2861{
2862 frm_nxt = frm;
2863 to_nxt = to;
2864 if (mode & generate_header)
2865 {
2866 if (to_end-to_nxt < 2)
2867 return codecvt_base::partial;
2868 *to_nxt++ = static_cast<uint8_t>(0xFF);
2869 *to_nxt++ = static_cast<uint8_t>(0xFE);
2870 }
2871 for (; frm_nxt < frm_end; ++frm_nxt)
2872 {
2873 uint16_t wc = *frm_nxt;
2874 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2875 return codecvt_base::error;
2876 if (to_end-to_nxt < 2)
2877 return codecvt_base::partial;
2878 *to_nxt++ = static_cast<uint8_t>(wc);
2879 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2880 }
2881 return codecvt_base::ok;
2882}
2883
2884static
2885codecvt_base::result
2886utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2887 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2888 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2889{
2890 frm_nxt = frm;
2891 to_nxt = to;
2892 if (mode & consume_header)
2893 {
2894 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2895 frm_nxt += 2;
2896 }
2897 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2898 {
2899 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2900 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2901 return codecvt_base::error;
2902 *to_nxt = c1;
2903 frm_nxt += 2;
2904 }
2905 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2906}
2907
2908static
2909int
2910utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2911 size_t mx, unsigned long Maxcode = 0x10FFFF,
2912 codecvt_mode mode = codecvt_mode(0))
2913{
2914 const uint8_t* frm_nxt = frm;
2915 frm_nxt = frm;
2916 if (mode & consume_header)
2917 {
2918 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2919 frm_nxt += 2;
2920 }
2921 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2922 {
2923 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2924 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2925 break;
2926 frm_nxt += 2;
2927 }
2928 return static_cast<int>(frm_nxt - frm);
2929}
2930
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002931// template <> class codecvt<char16_t, char, mbstate_t>
2932
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002933locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002934
2935codecvt<char16_t, char, mbstate_t>::~codecvt()
2936{
2937}
2938
2939codecvt<char16_t, char, mbstate_t>::result
2940codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002941 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002942 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2943{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002944 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2945 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2946 const uint16_t* _frm_nxt = _frm;
2947 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2948 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2949 uint8_t* _to_nxt = _to;
2950 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2951 frm_nxt = frm + (_frm_nxt - _frm);
2952 to_nxt = to + (_to_nxt - _to);
2953 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002954}
2955
2956codecvt<char16_t, char, mbstate_t>::result
2957codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002958 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002959 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2960{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002961 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2962 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2963 const uint8_t* _frm_nxt = _frm;
2964 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2965 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2966 uint16_t* _to_nxt = _to;
2967 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2968 frm_nxt = frm + (_frm_nxt - _frm);
2969 to_nxt = to + (_to_nxt - _to);
2970 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002971}
2972
2973codecvt<char16_t, char, mbstate_t>::result
2974codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2975 extern_type* to, extern_type*, extern_type*& to_nxt) const
2976{
2977 to_nxt = to;
2978 return noconv;
2979}
2980
2981int
Howard Hinnantc9834542011-05-31 15:34:58 +00002982codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002983{
2984 return 0;
2985}
2986
2987bool
Howard Hinnantc9834542011-05-31 15:34:58 +00002988codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002989{
2990 return false;
2991}
2992
2993int
2994codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2995 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2996{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002997 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2998 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2999 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003000}
3001
3002int
Howard Hinnantc9834542011-05-31 15:34:58 +00003003codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003004{
3005 return 4;
3006}
3007
3008// template <> class codecvt<char32_t, char, mbstate_t>
3009
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003010locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003011
3012codecvt<char32_t, char, mbstate_t>::~codecvt()
3013{
3014}
3015
3016codecvt<char32_t, char, mbstate_t>::result
3017codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003018 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003019 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3020{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003021 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3022 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3023 const uint32_t* _frm_nxt = _frm;
3024 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3025 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3026 uint8_t* _to_nxt = _to;
3027 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3028 frm_nxt = frm + (_frm_nxt - _frm);
3029 to_nxt = to + (_to_nxt - _to);
3030 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003031}
3032
3033codecvt<char32_t, char, mbstate_t>::result
3034codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003035 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003036 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3037{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003038 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3039 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3040 const uint8_t* _frm_nxt = _frm;
3041 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3042 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3043 uint32_t* _to_nxt = _to;
3044 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3045 frm_nxt = frm + (_frm_nxt - _frm);
3046 to_nxt = to + (_to_nxt - _to);
3047 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003048}
3049
3050codecvt<char32_t, char, mbstate_t>::result
3051codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3052 extern_type* to, extern_type*, extern_type*& to_nxt) const
3053{
3054 to_nxt = to;
3055 return noconv;
3056}
3057
3058int
Howard Hinnantc9834542011-05-31 15:34:58 +00003059codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003060{
3061 return 0;
3062}
3063
3064bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003065codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003066{
3067 return false;
3068}
3069
3070int
3071codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3072 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3073{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003074 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3075 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3076 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003077}
3078
3079int
Howard Hinnantc9834542011-05-31 15:34:58 +00003080codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003081{
3082 return 4;
3083}
3084
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003085// __codecvt_utf8<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003086
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003087__codecvt_utf8<wchar_t>::result
3088__codecvt_utf8<wchar_t>::do_out(state_type&,
3089 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003090 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3091{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003092 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3093 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3094 const uint32_t* _frm_nxt = _frm;
3095 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3096 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3097 uint8_t* _to_nxt = _to;
3098 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3099 _Maxcode_, _Mode_);
3100 frm_nxt = frm + (_frm_nxt - _frm);
3101 to_nxt = to + (_to_nxt - _to);
3102 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003103}
3104
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003105__codecvt_utf8<wchar_t>::result
3106__codecvt_utf8<wchar_t>::do_in(state_type&,
3107 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003108 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3109{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003110 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3111 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3112 const uint8_t* _frm_nxt = _frm;
3113 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3114 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3115 uint32_t* _to_nxt = _to;
3116 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3117 _Maxcode_, _Mode_);
3118 frm_nxt = frm + (_frm_nxt - _frm);
3119 to_nxt = to + (_to_nxt - _to);
3120 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003121}
3122
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003123__codecvt_utf8<wchar_t>::result
3124__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003125 extern_type* to, extern_type*, extern_type*& to_nxt) const
3126{
3127 to_nxt = to;
3128 return noconv;
3129}
3130
3131int
Howard Hinnantc9834542011-05-31 15:34:58 +00003132__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003133{
3134 return 0;
3135}
3136
3137bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003138__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003139{
3140 return false;
3141}
3142
3143int
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003144__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003145 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3146{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003147 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3148 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3149 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003150}
3151
3152int
Howard Hinnantc9834542011-05-31 15:34:58 +00003153__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003154{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003155 if (_Mode_ & consume_header)
3156 return 7;
3157 return 4;
3158}
3159
3160// __codecvt_utf8<char16_t>
3161
3162__codecvt_utf8<char16_t>::result
3163__codecvt_utf8<char16_t>::do_out(state_type&,
3164 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3165 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3166{
3167 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3168 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3169 const uint16_t* _frm_nxt = _frm;
3170 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3171 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3172 uint8_t* _to_nxt = _to;
3173 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3174 _Maxcode_, _Mode_);
3175 frm_nxt = frm + (_frm_nxt - _frm);
3176 to_nxt = to + (_to_nxt - _to);
3177 return r;
3178}
3179
3180__codecvt_utf8<char16_t>::result
3181__codecvt_utf8<char16_t>::do_in(state_type&,
3182 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3183 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3184{
3185 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3186 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3187 const uint8_t* _frm_nxt = _frm;
3188 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3189 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3190 uint16_t* _to_nxt = _to;
3191 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3192 _Maxcode_, _Mode_);
3193 frm_nxt = frm + (_frm_nxt - _frm);
3194 to_nxt = to + (_to_nxt - _to);
3195 return r;
3196}
3197
3198__codecvt_utf8<char16_t>::result
3199__codecvt_utf8<char16_t>::do_unshift(state_type&,
3200 extern_type* to, extern_type*, extern_type*& to_nxt) const
3201{
3202 to_nxt = to;
3203 return noconv;
3204}
3205
3206int
Howard Hinnantc9834542011-05-31 15:34:58 +00003207__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003208{
3209 return 0;
3210}
3211
3212bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003213__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003214{
3215 return false;
3216}
3217
3218int
3219__codecvt_utf8<char16_t>::do_length(state_type&,
3220 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3221{
3222 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3223 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3224 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3225}
3226
3227int
Howard Hinnantc9834542011-05-31 15:34:58 +00003228__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003229{
3230 if (_Mode_ & consume_header)
3231 return 6;
3232 return 3;
3233}
3234
3235// __codecvt_utf8<char32_t>
3236
3237__codecvt_utf8<char32_t>::result
3238__codecvt_utf8<char32_t>::do_out(state_type&,
3239 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3240 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3241{
3242 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3243 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3244 const uint32_t* _frm_nxt = _frm;
3245 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3246 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3247 uint8_t* _to_nxt = _to;
3248 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3249 _Maxcode_, _Mode_);
3250 frm_nxt = frm + (_frm_nxt - _frm);
3251 to_nxt = to + (_to_nxt - _to);
3252 return r;
3253}
3254
3255__codecvt_utf8<char32_t>::result
3256__codecvt_utf8<char32_t>::do_in(state_type&,
3257 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3258 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3259{
3260 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3261 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3262 const uint8_t* _frm_nxt = _frm;
3263 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3264 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3265 uint32_t* _to_nxt = _to;
3266 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3267 _Maxcode_, _Mode_);
3268 frm_nxt = frm + (_frm_nxt - _frm);
3269 to_nxt = to + (_to_nxt - _to);
3270 return r;
3271}
3272
3273__codecvt_utf8<char32_t>::result
3274__codecvt_utf8<char32_t>::do_unshift(state_type&,
3275 extern_type* to, extern_type*, extern_type*& to_nxt) const
3276{
3277 to_nxt = to;
3278 return noconv;
3279}
3280
3281int
Howard Hinnantc9834542011-05-31 15:34:58 +00003282__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003283{
3284 return 0;
3285}
3286
3287bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003288__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003289{
3290 return false;
3291}
3292
3293int
3294__codecvt_utf8<char32_t>::do_length(state_type&,
3295 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3296{
3297 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3298 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3299 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3300}
3301
3302int
Howard Hinnantc9834542011-05-31 15:34:58 +00003303__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003304{
3305 if (_Mode_ & consume_header)
3306 return 7;
3307 return 4;
3308}
3309
3310// __codecvt_utf16<wchar_t, false>
3311
3312__codecvt_utf16<wchar_t, false>::result
3313__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3314 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3315 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3316{
3317 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3318 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3319 const uint32_t* _frm_nxt = _frm;
3320 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3321 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3322 uint8_t* _to_nxt = _to;
3323 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3324 _Maxcode_, _Mode_);
3325 frm_nxt = frm + (_frm_nxt - _frm);
3326 to_nxt = to + (_to_nxt - _to);
3327 return r;
3328}
3329
3330__codecvt_utf16<wchar_t, false>::result
3331__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3332 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3333 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3334{
3335 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3336 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3337 const uint8_t* _frm_nxt = _frm;
3338 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3339 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3340 uint32_t* _to_nxt = _to;
3341 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3342 _Maxcode_, _Mode_);
3343 frm_nxt = frm + (_frm_nxt - _frm);
3344 to_nxt = to + (_to_nxt - _to);
3345 return r;
3346}
3347
3348__codecvt_utf16<wchar_t, false>::result
3349__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3350 extern_type* to, extern_type*, extern_type*& to_nxt) const
3351{
3352 to_nxt = to;
3353 return noconv;
3354}
3355
3356int
Howard Hinnantc9834542011-05-31 15:34:58 +00003357__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003358{
3359 return 0;
3360}
3361
3362bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003363__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003364{
3365 return false;
3366}
3367
3368int
3369__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3370 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3371{
3372 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3373 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3374 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3375}
3376
3377int
Howard Hinnantc9834542011-05-31 15:34:58 +00003378__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003379{
3380 if (_Mode_ & consume_header)
3381 return 6;
3382 return 4;
3383}
3384
3385// __codecvt_utf16<wchar_t, true>
3386
3387__codecvt_utf16<wchar_t, true>::result
3388__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3389 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3390 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3391{
3392 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3393 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3394 const uint32_t* _frm_nxt = _frm;
3395 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3396 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3397 uint8_t* _to_nxt = _to;
3398 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3399 _Maxcode_, _Mode_);
3400 frm_nxt = frm + (_frm_nxt - _frm);
3401 to_nxt = to + (_to_nxt - _to);
3402 return r;
3403}
3404
3405__codecvt_utf16<wchar_t, true>::result
3406__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3407 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3408 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3409{
3410 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3411 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3412 const uint8_t* _frm_nxt = _frm;
3413 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3414 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3415 uint32_t* _to_nxt = _to;
3416 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3417 _Maxcode_, _Mode_);
3418 frm_nxt = frm + (_frm_nxt - _frm);
3419 to_nxt = to + (_to_nxt - _to);
3420 return r;
3421}
3422
3423__codecvt_utf16<wchar_t, true>::result
3424__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3425 extern_type* to, extern_type*, extern_type*& to_nxt) const
3426{
3427 to_nxt = to;
3428 return noconv;
3429}
3430
3431int
Howard Hinnantc9834542011-05-31 15:34:58 +00003432__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003433{
3434 return 0;
3435}
3436
3437bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003438__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003439{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003440 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003441}
3442
3443int
3444__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3445 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3446{
3447 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3448 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3449 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3450}
3451
3452int
Howard Hinnantc9834542011-05-31 15:34:58 +00003453__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003454{
3455 if (_Mode_ & consume_header)
3456 return 6;
3457 return 4;
3458}
3459
3460// __codecvt_utf16<char16_t, false>
3461
3462__codecvt_utf16<char16_t, false>::result
3463__codecvt_utf16<char16_t, false>::do_out(state_type&,
3464 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3465 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3466{
3467 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3468 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3469 const uint16_t* _frm_nxt = _frm;
3470 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3471 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3472 uint8_t* _to_nxt = _to;
3473 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3474 _Maxcode_, _Mode_);
3475 frm_nxt = frm + (_frm_nxt - _frm);
3476 to_nxt = to + (_to_nxt - _to);
3477 return r;
3478}
3479
3480__codecvt_utf16<char16_t, false>::result
3481__codecvt_utf16<char16_t, false>::do_in(state_type&,
3482 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3483 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3484{
3485 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3486 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3487 const uint8_t* _frm_nxt = _frm;
3488 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3489 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3490 uint16_t* _to_nxt = _to;
3491 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3492 _Maxcode_, _Mode_);
3493 frm_nxt = frm + (_frm_nxt - _frm);
3494 to_nxt = to + (_to_nxt - _to);
3495 return r;
3496}
3497
3498__codecvt_utf16<char16_t, false>::result
3499__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3500 extern_type* to, extern_type*, extern_type*& to_nxt) const
3501{
3502 to_nxt = to;
3503 return noconv;
3504}
3505
3506int
Howard Hinnantc9834542011-05-31 15:34:58 +00003507__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003508{
3509 return 0;
3510}
3511
3512bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003513__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003514{
3515 return false;
3516}
3517
3518int
3519__codecvt_utf16<char16_t, false>::do_length(state_type&,
3520 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3521{
3522 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3523 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3524 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3525}
3526
3527int
Howard Hinnantc9834542011-05-31 15:34:58 +00003528__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003529{
3530 if (_Mode_ & consume_header)
3531 return 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003532 return 2;
3533}
3534
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003535// __codecvt_utf16<char16_t, true>
3536
3537__codecvt_utf16<char16_t, true>::result
3538__codecvt_utf16<char16_t, true>::do_out(state_type&,
3539 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3540 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3541{
3542 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3543 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3544 const uint16_t* _frm_nxt = _frm;
3545 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3546 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3547 uint8_t* _to_nxt = _to;
3548 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3549 _Maxcode_, _Mode_);
3550 frm_nxt = frm + (_frm_nxt - _frm);
3551 to_nxt = to + (_to_nxt - _to);
3552 return r;
3553}
3554
3555__codecvt_utf16<char16_t, true>::result
3556__codecvt_utf16<char16_t, true>::do_in(state_type&,
3557 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3558 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3559{
3560 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3561 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3562 const uint8_t* _frm_nxt = _frm;
3563 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3564 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3565 uint16_t* _to_nxt = _to;
3566 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3567 _Maxcode_, _Mode_);
3568 frm_nxt = frm + (_frm_nxt - _frm);
3569 to_nxt = to + (_to_nxt - _to);
3570 return r;
3571}
3572
3573__codecvt_utf16<char16_t, true>::result
3574__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3575 extern_type* to, extern_type*, extern_type*& to_nxt) const
3576{
3577 to_nxt = to;
3578 return noconv;
3579}
3580
3581int
Howard Hinnantc9834542011-05-31 15:34:58 +00003582__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003583{
3584 return 0;
3585}
3586
3587bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003588__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003589{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003590 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003591}
3592
3593int
3594__codecvt_utf16<char16_t, true>::do_length(state_type&,
3595 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3596{
3597 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3598 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3599 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3600}
3601
3602int
Howard Hinnantc9834542011-05-31 15:34:58 +00003603__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003604{
3605 if (_Mode_ & consume_header)
3606 return 4;
3607 return 2;
3608}
3609
3610// __codecvt_utf16<char32_t, false>
3611
3612__codecvt_utf16<char32_t, false>::result
3613__codecvt_utf16<char32_t, false>::do_out(state_type&,
3614 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3615 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3616{
3617 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3618 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3619 const uint32_t* _frm_nxt = _frm;
3620 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3621 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3622 uint8_t* _to_nxt = _to;
3623 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3624 _Maxcode_, _Mode_);
3625 frm_nxt = frm + (_frm_nxt - _frm);
3626 to_nxt = to + (_to_nxt - _to);
3627 return r;
3628}
3629
3630__codecvt_utf16<char32_t, false>::result
3631__codecvt_utf16<char32_t, false>::do_in(state_type&,
3632 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3633 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3634{
3635 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3636 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3637 const uint8_t* _frm_nxt = _frm;
3638 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3639 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3640 uint32_t* _to_nxt = _to;
3641 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3642 _Maxcode_, _Mode_);
3643 frm_nxt = frm + (_frm_nxt - _frm);
3644 to_nxt = to + (_to_nxt - _to);
3645 return r;
3646}
3647
3648__codecvt_utf16<char32_t, false>::result
3649__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3650 extern_type* to, extern_type*, extern_type*& to_nxt) const
3651{
3652 to_nxt = to;
3653 return noconv;
3654}
3655
3656int
Howard Hinnantc9834542011-05-31 15:34:58 +00003657__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003658{
3659 return 0;
3660}
3661
3662bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003663__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003664{
3665 return false;
3666}
3667
3668int
3669__codecvt_utf16<char32_t, false>::do_length(state_type&,
3670 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3671{
3672 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3673 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3674 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3675}
3676
3677int
Howard Hinnantc9834542011-05-31 15:34:58 +00003678__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003679{
3680 if (_Mode_ & consume_header)
3681 return 6;
3682 return 4;
3683}
3684
3685// __codecvt_utf16<char32_t, true>
3686
3687__codecvt_utf16<char32_t, true>::result
3688__codecvt_utf16<char32_t, true>::do_out(state_type&,
3689 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3690 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3691{
3692 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3693 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3694 const uint32_t* _frm_nxt = _frm;
3695 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3696 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3697 uint8_t* _to_nxt = _to;
3698 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3699 _Maxcode_, _Mode_);
3700 frm_nxt = frm + (_frm_nxt - _frm);
3701 to_nxt = to + (_to_nxt - _to);
3702 return r;
3703}
3704
3705__codecvt_utf16<char32_t, true>::result
3706__codecvt_utf16<char32_t, true>::do_in(state_type&,
3707 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3708 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3709{
3710 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3711 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3712 const uint8_t* _frm_nxt = _frm;
3713 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3714 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3715 uint32_t* _to_nxt = _to;
3716 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3717 _Maxcode_, _Mode_);
3718 frm_nxt = frm + (_frm_nxt - _frm);
3719 to_nxt = to + (_to_nxt - _to);
3720 return r;
3721}
3722
3723__codecvt_utf16<char32_t, true>::result
3724__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3725 extern_type* to, extern_type*, extern_type*& to_nxt) const
3726{
3727 to_nxt = to;
3728 return noconv;
3729}
3730
3731int
Howard Hinnantc9834542011-05-31 15:34:58 +00003732__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003733{
3734 return 0;
3735}
3736
3737bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003738__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003739{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003740 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003741}
3742
3743int
3744__codecvt_utf16<char32_t, true>::do_length(state_type&,
3745 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3746{
3747 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3748 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3749 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3750}
3751
3752int
Howard Hinnantc9834542011-05-31 15:34:58 +00003753__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003754{
3755 if (_Mode_ & consume_header)
3756 return 6;
3757 return 4;
3758}
3759
3760// __codecvt_utf8_utf16<wchar_t>
3761
3762__codecvt_utf8_utf16<wchar_t>::result
3763__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3764 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3765 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3766{
3767 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3768 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3769 const uint32_t* _frm_nxt = _frm;
3770 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3771 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3772 uint8_t* _to_nxt = _to;
3773 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3774 _Maxcode_, _Mode_);
3775 frm_nxt = frm + (_frm_nxt - _frm);
3776 to_nxt = to + (_to_nxt - _to);
3777 return r;
3778}
3779
3780__codecvt_utf8_utf16<wchar_t>::result
3781__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3782 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3783 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3784{
3785 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3786 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3787 const uint8_t* _frm_nxt = _frm;
3788 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3789 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3790 uint32_t* _to_nxt = _to;
3791 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3792 _Maxcode_, _Mode_);
3793 frm_nxt = frm + (_frm_nxt - _frm);
3794 to_nxt = to + (_to_nxt - _to);
3795 return r;
3796}
3797
3798__codecvt_utf8_utf16<wchar_t>::result
3799__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3800 extern_type* to, extern_type*, extern_type*& to_nxt) const
3801{
3802 to_nxt = to;
3803 return noconv;
3804}
3805
3806int
Howard Hinnantc9834542011-05-31 15:34:58 +00003807__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003808{
3809 return 0;
3810}
3811
3812bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003813__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003814{
3815 return false;
3816}
3817
3818int
3819__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3820 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3821{
3822 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3823 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3824 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3825}
3826
3827int
Howard Hinnantc9834542011-05-31 15:34:58 +00003828__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003829{
3830 if (_Mode_ & consume_header)
3831 return 7;
3832 return 4;
3833}
3834
3835// __codecvt_utf8_utf16<char16_t>
3836
3837__codecvt_utf8_utf16<char16_t>::result
3838__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3839 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3840 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3841{
3842 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3843 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3844 const uint16_t* _frm_nxt = _frm;
3845 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3846 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3847 uint8_t* _to_nxt = _to;
3848 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3849 _Maxcode_, _Mode_);
3850 frm_nxt = frm + (_frm_nxt - _frm);
3851 to_nxt = to + (_to_nxt - _to);
3852 return r;
3853}
3854
3855__codecvt_utf8_utf16<char16_t>::result
3856__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3857 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3858 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3859{
3860 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3861 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3862 const uint8_t* _frm_nxt = _frm;
3863 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3864 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3865 uint16_t* _to_nxt = _to;
3866 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3867 _Maxcode_, _Mode_);
3868 frm_nxt = frm + (_frm_nxt - _frm);
3869 to_nxt = to + (_to_nxt - _to);
3870 return r;
3871}
3872
3873__codecvt_utf8_utf16<char16_t>::result
3874__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3875 extern_type* to, extern_type*, extern_type*& to_nxt) const
3876{
3877 to_nxt = to;
3878 return noconv;
3879}
3880
3881int
Howard Hinnantc9834542011-05-31 15:34:58 +00003882__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003883{
3884 return 0;
3885}
3886
3887bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003888__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003889{
3890 return false;
3891}
3892
3893int
3894__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3895 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3896{
3897 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3898 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3899 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3900}
3901
3902int
Howard Hinnantc9834542011-05-31 15:34:58 +00003903__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003904{
3905 if (_Mode_ & consume_header)
3906 return 7;
3907 return 4;
3908}
3909
3910// __codecvt_utf8_utf16<char32_t>
3911
3912__codecvt_utf8_utf16<char32_t>::result
3913__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3914 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3915 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3916{
3917 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3918 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3919 const uint32_t* _frm_nxt = _frm;
3920 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3921 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3922 uint8_t* _to_nxt = _to;
3923 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3924 _Maxcode_, _Mode_);
3925 frm_nxt = frm + (_frm_nxt - _frm);
3926 to_nxt = to + (_to_nxt - _to);
3927 return r;
3928}
3929
3930__codecvt_utf8_utf16<char32_t>::result
3931__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3932 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3933 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3934{
3935 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3936 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3937 const uint8_t* _frm_nxt = _frm;
3938 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3939 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3940 uint32_t* _to_nxt = _to;
3941 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3942 _Maxcode_, _Mode_);
3943 frm_nxt = frm + (_frm_nxt - _frm);
3944 to_nxt = to + (_to_nxt - _to);
3945 return r;
3946}
3947
3948__codecvt_utf8_utf16<char32_t>::result
3949__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3950 extern_type* to, extern_type*, extern_type*& to_nxt) const
3951{
3952 to_nxt = to;
3953 return noconv;
3954}
3955
3956int
Howard Hinnantc9834542011-05-31 15:34:58 +00003957__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003958{
3959 return 0;
3960}
3961
3962bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003963__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003964{
3965 return false;
3966}
3967
3968int
3969__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3970 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3971{
3972 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3973 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3974 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3975}
3976
3977int
Howard Hinnantc9834542011-05-31 15:34:58 +00003978__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003979{
3980 if (_Mode_ & consume_header)
3981 return 7;
3982 return 4;
3983}
3984
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003985// __narrow_to_utf8<16>
3986
3987__narrow_to_utf8<16>::~__narrow_to_utf8()
3988{
3989}
3990
3991// __narrow_to_utf8<32>
3992
3993__narrow_to_utf8<32>::~__narrow_to_utf8()
3994{
3995}
3996
3997// __widen_from_utf8<16>
3998
3999__widen_from_utf8<16>::~__widen_from_utf8()
4000{
4001}
4002
4003// __widen_from_utf8<32>
4004
4005__widen_from_utf8<32>::~__widen_from_utf8()
4006{
4007}
4008
4009// numpunct<char> && numpunct<wchar_t>
4010
4011locale::id numpunct< char >::id;
4012locale::id numpunct<wchar_t>::id;
4013
4014numpunct<char>::numpunct(size_t refs)
4015 : locale::facet(refs),
4016 __decimal_point_('.'),
4017 __thousands_sep_(',')
4018{
4019}
4020
4021numpunct<wchar_t>::numpunct(size_t refs)
4022 : locale::facet(refs),
4023 __decimal_point_(L'.'),
4024 __thousands_sep_(L',')
4025{
4026}
4027
4028numpunct<char>::~numpunct()
4029{
4030}
4031
4032numpunct<wchar_t>::~numpunct()
4033{
4034}
4035
4036 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4037wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4038
4039 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4040wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4041
4042string numpunct< char >::do_grouping() const {return __grouping_;}
4043string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4044
4045 string numpunct< char >::do_truename() const {return "true";}
4046wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4047
4048 string numpunct< char >::do_falsename() const {return "false";}
4049wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4050
4051// numpunct_byname<char>
4052
4053numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4054 : numpunct<char>(refs)
4055{
4056 __init(nm);
4057}
4058
4059numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4060 : numpunct<char>(refs)
4061{
4062 __init(nm.c_str());
4063}
4064
4065numpunct_byname<char>::~numpunct_byname()
4066{
4067}
4068
4069void
4070numpunct_byname<char>::__init(const char* nm)
4071{
4072 if (strcmp(nm, "C") != 0)
4073 {
Sean Huntf3907e62011-07-15 05:40:33 +00004074 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004075#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004076 if (loc == 0)
4077 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4078 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004079#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004080#ifdef _LIBCPP_STABLE_APPLE_ABI
4081 lconv* lc = localeconv_l(loc.get());
4082#else
4083 lconv* lc = __localeconv_l(loc.get());
4084#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004085 if (*lc->decimal_point)
4086 __decimal_point_ = *lc->decimal_point;
4087 if (*lc->thousands_sep)
4088 __thousands_sep_ = *lc->thousands_sep;
4089 __grouping_ = lc->grouping;
Sean Huntcb05a082011-07-07 22:45:07 +00004090 // localization for truename and falsename is not available
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004091 }
4092}
4093
4094// numpunct_byname<wchar_t>
4095
4096numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4097 : numpunct<wchar_t>(refs)
4098{
4099 __init(nm);
4100}
4101
4102numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4103 : numpunct<wchar_t>(refs)
4104{
4105 __init(nm.c_str());
4106}
4107
4108numpunct_byname<wchar_t>::~numpunct_byname()
4109{
4110}
4111
4112void
4113numpunct_byname<wchar_t>::__init(const char* nm)
4114{
4115 if (strcmp(nm, "C") != 0)
4116 {
Sean Huntf3907e62011-07-15 05:40:33 +00004117 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004118#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004119 if (loc == 0)
4120 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4121 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004122#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004123#ifdef _LIBCPP_STABLE_APPLE_ABI
4124 lconv* lc = localeconv_l(loc.get());
4125#else
4126 lconv* lc = __localeconv_l(loc.get());
4127#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004128 if (*lc->decimal_point)
4129 __decimal_point_ = *lc->decimal_point;
4130 if (*lc->thousands_sep)
4131 __thousands_sep_ = *lc->thousands_sep;
4132 __grouping_ = lc->grouping;
4133 // locallization for truename and falsename is not available
4134 }
4135}
4136
4137// num_get helpers
4138
4139int
4140__num_get_base::__get_base(ios_base& iob)
4141{
4142 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4143 if (__basefield == ios_base::oct)
4144 return 8;
4145 else if (__basefield == ios_base::hex)
4146 return 16;
4147 else if (__basefield == 0)
4148 return 0;
4149 return 10;
4150}
4151
4152const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4153
4154void
4155__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4156 ios_base::iostate& __err)
4157{
4158 if (__grouping.size() != 0)
4159 {
4160 reverse(__g, __g_end);
4161 const char* __ig = __grouping.data();
4162 const char* __eg = __ig + __grouping.size();
4163 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4164 {
4165 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4166 {
4167 if (*__ig != *__r)
4168 {
4169 __err = ios_base::failbit;
4170 return;
4171 }
4172 }
4173 if (__eg - __ig > 1)
4174 ++__ig;
4175 }
4176 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4177 {
4178 if (*__ig < __g_end[-1] || __g_end[-1] == 0)
4179 __err = ios_base::failbit;
4180 }
4181 }
4182}
4183
4184void
4185__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4186 ios_base::fmtflags __flags)
4187{
4188 if (__flags & ios_base::showpos)
4189 *__fmtp++ = '+';
4190 if (__flags & ios_base::showbase)
4191 *__fmtp++ = '#';
4192 while(*__len)
4193 *__fmtp++ = *__len++;
4194 if ((__flags & ios_base::basefield) == ios_base::oct)
4195 *__fmtp = 'o';
4196 else if ((__flags & ios_base::basefield) == ios_base::hex)
4197 {
4198 if (__flags & ios_base::uppercase)
4199 *__fmtp = 'X';
4200 else
4201 *__fmtp = 'x';
4202 }
4203 else if (__signd)
4204 *__fmtp = 'd';
4205 else
4206 *__fmtp = 'u';
4207}
4208
4209bool
4210__num_put_base::__format_float(char* __fmtp, const char* __len,
4211 ios_base::fmtflags __flags)
4212{
4213 bool specify_precision = true;
4214 if (__flags & ios_base::showpos)
4215 *__fmtp++ = '+';
4216 if (__flags & ios_base::showpoint)
4217 *__fmtp++ = '#';
4218 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4219 bool uppercase = __flags & ios_base::uppercase;
4220 if (floatfield == (ios_base::fixed | ios_base::scientific))
4221 specify_precision = false;
4222 else
4223 {
4224 *__fmtp++ = '.';
4225 *__fmtp++ = '*';
4226 }
4227 while(*__len)
4228 *__fmtp++ = *__len++;
4229 if (floatfield == ios_base::fixed)
4230 {
4231 if (uppercase)
4232 *__fmtp = 'F';
4233 else
4234 *__fmtp = 'f';
4235 }
4236 else if (floatfield == ios_base::scientific)
4237 {
4238 if (uppercase)
4239 *__fmtp = 'E';
4240 else
4241 *__fmtp = 'e';
4242 }
4243 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4244 {
4245 if (uppercase)
4246 *__fmtp = 'A';
4247 else
4248 *__fmtp = 'a';
4249 }
4250 else
4251 {
4252 if (uppercase)
4253 *__fmtp = 'G';
4254 else
4255 *__fmtp = 'g';
4256 }
4257 return specify_precision;
4258}
4259
4260char*
4261__num_put_base::__identify_padding(char* __nb, char* __ne,
4262 const ios_base& __iob)
4263{
4264 switch (__iob.flags() & ios_base::adjustfield)
4265 {
4266 case ios_base::internal:
4267 if (__nb[0] == '-' || __nb[0] == '+')
4268 return __nb+1;
4269 if (__ne - __nb >= 2 && __nb[0] == '0'
4270 && (__nb[1] == 'x' || __nb[1] == 'X'))
4271 return __nb+2;
4272 break;
4273 case ios_base::left:
4274 return __ne;
4275 case ios_base::right:
4276 default:
4277 break;
4278 }
4279 return __nb;
4280}
4281
4282// time_get
4283
4284static
4285string*
4286init_weeks()
4287{
4288 static string weeks[14];
4289 weeks[0] = "Sunday";
4290 weeks[1] = "Monday";
4291 weeks[2] = "Tuesday";
4292 weeks[3] = "Wednesday";
4293 weeks[4] = "Thursday";
4294 weeks[5] = "Friday";
4295 weeks[6] = "Saturday";
4296 weeks[7] = "Sun";
4297 weeks[8] = "Mon";
4298 weeks[9] = "Tue";
4299 weeks[10] = "Wed";
4300 weeks[11] = "Thu";
4301 weeks[12] = "Fri";
4302 weeks[13] = "Sat";
4303 return weeks;
4304}
4305
4306static
4307wstring*
4308init_wweeks()
4309{
4310 static wstring weeks[14];
4311 weeks[0] = L"Sunday";
4312 weeks[1] = L"Monday";
4313 weeks[2] = L"Tuesday";
4314 weeks[3] = L"Wednesday";
4315 weeks[4] = L"Thursday";
4316 weeks[5] = L"Friday";
4317 weeks[6] = L"Saturday";
4318 weeks[7] = L"Sun";
4319 weeks[8] = L"Mon";
4320 weeks[9] = L"Tue";
4321 weeks[10] = L"Wed";
4322 weeks[11] = L"Thu";
4323 weeks[12] = L"Fri";
4324 weeks[13] = L"Sat";
4325 return weeks;
4326}
4327
4328template <>
4329const string*
4330__time_get_c_storage<char>::__weeks() const
4331{
4332 static const string* weeks = init_weeks();
4333 return weeks;
4334}
4335
4336template <>
4337const wstring*
4338__time_get_c_storage<wchar_t>::__weeks() const
4339{
4340 static const wstring* weeks = init_wweeks();
4341 return weeks;
4342}
4343
4344static
4345string*
4346init_months()
4347{
4348 static string months[24];
4349 months[0] = "January";
4350 months[1] = "February";
4351 months[2] = "March";
4352 months[3] = "April";
4353 months[4] = "May";
4354 months[5] = "June";
4355 months[6] = "July";
4356 months[7] = "August";
4357 months[8] = "September";
4358 months[9] = "October";
4359 months[10] = "November";
4360 months[11] = "December";
4361 months[12] = "Jan";
4362 months[13] = "Feb";
4363 months[14] = "Mar";
4364 months[15] = "Apr";
4365 months[16] = "May";
4366 months[17] = "Jun";
4367 months[18] = "Jul";
4368 months[19] = "Aug";
4369 months[20] = "Sep";
4370 months[21] = "Oct";
4371 months[22] = "Nov";
4372 months[23] = "Dec";
4373 return months;
4374}
4375
4376static
4377wstring*
4378init_wmonths()
4379{
4380 static wstring months[24];
4381 months[0] = L"January";
4382 months[1] = L"February";
4383 months[2] = L"March";
4384 months[3] = L"April";
4385 months[4] = L"May";
4386 months[5] = L"June";
4387 months[6] = L"July";
4388 months[7] = L"August";
4389 months[8] = L"September";
4390 months[9] = L"October";
4391 months[10] = L"November";
4392 months[11] = L"December";
4393 months[12] = L"Jan";
4394 months[13] = L"Feb";
4395 months[14] = L"Mar";
4396 months[15] = L"Apr";
4397 months[16] = L"May";
4398 months[17] = L"Jun";
4399 months[18] = L"Jul";
4400 months[19] = L"Aug";
4401 months[20] = L"Sep";
4402 months[21] = L"Oct";
4403 months[22] = L"Nov";
4404 months[23] = L"Dec";
4405 return months;
4406}
4407
4408template <>
4409const string*
4410__time_get_c_storage<char>::__months() const
4411{
4412 static const string* months = init_months();
4413 return months;
4414}
4415
4416template <>
4417const wstring*
4418__time_get_c_storage<wchar_t>::__months() const
4419{
4420 static const wstring* months = init_wmonths();
4421 return months;
4422}
4423
4424static
4425string*
4426init_am_pm()
4427{
4428 static string am_pm[24];
4429 am_pm[0] = "AM";
4430 am_pm[1] = "PM";
4431 return am_pm;
4432}
4433
4434static
4435wstring*
4436init_wam_pm()
4437{
4438 static wstring am_pm[24];
4439 am_pm[0] = L"AM";
4440 am_pm[1] = L"PM";
4441 return am_pm;
4442}
4443
4444template <>
4445const string*
4446__time_get_c_storage<char>::__am_pm() const
4447{
4448 static const string* am_pm = init_am_pm();
4449 return am_pm;
4450}
4451
4452template <>
4453const wstring*
4454__time_get_c_storage<wchar_t>::__am_pm() const
4455{
4456 static const wstring* am_pm = init_wam_pm();
4457 return am_pm;
4458}
4459
4460template <>
4461const string&
4462__time_get_c_storage<char>::__x() const
4463{
4464 static string s("%m/%d/%y");
4465 return s;
4466}
4467
4468template <>
4469const wstring&
4470__time_get_c_storage<wchar_t>::__x() const
4471{
4472 static wstring s(L"%m/%d/%y");
4473 return s;
4474}
4475
4476template <>
4477const string&
4478__time_get_c_storage<char>::__X() const
4479{
4480 static string s("%H:%M:%S");
4481 return s;
4482}
4483
4484template <>
4485const wstring&
4486__time_get_c_storage<wchar_t>::__X() const
4487{
4488 static wstring s(L"%H:%M:%S");
4489 return s;
4490}
4491
4492template <>
4493const string&
4494__time_get_c_storage<char>::__c() const
4495{
4496 static string s("%a %b %d %H:%M:%S %Y");
4497 return s;
4498}
4499
4500template <>
4501const wstring&
4502__time_get_c_storage<wchar_t>::__c() const
4503{
4504 static wstring s(L"%a %b %d %H:%M:%S %Y");
4505 return s;
4506}
4507
4508template <>
4509const string&
4510__time_get_c_storage<char>::__r() const
4511{
4512 static string s("%I:%M:%S %p");
4513 return s;
4514}
4515
4516template <>
4517const wstring&
4518__time_get_c_storage<wchar_t>::__r() const
4519{
4520 static wstring s(L"%I:%M:%S %p");
4521 return s;
4522}
4523
4524// time_get_byname
4525
4526__time_get::__time_get(const char* nm)
4527 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4528{
Howard Hinnantd4444702010-08-11 17:04:31 +00004529#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004530 if (__loc_ == 0)
4531 throw runtime_error("time_get_byname"
4532 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004533#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004534}
4535
4536__time_get::__time_get(const string& nm)
4537 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4538{
Howard Hinnantd4444702010-08-11 17:04:31 +00004539#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004540 if (__loc_ == 0)
4541 throw runtime_error("time_get_byname"
4542 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004543#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004544}
4545
4546__time_get::~__time_get()
4547{
4548 freelocale(__loc_);
4549}
4550
4551template <>
4552string
4553__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4554{
4555 tm t;
4556 t.tm_sec = 59;
4557 t.tm_min = 55;
4558 t.tm_hour = 23;
4559 t.tm_mday = 31;
4560 t.tm_mon = 11;
4561 t.tm_year = 161;
4562 t.tm_wday = 6;
4563 t.tm_yday = 364;
4564 t.tm_isdst = -1;
4565 char buf[100];
4566 char f[3] = {0};
4567 f[0] = '%';
4568 f[1] = fmt;
4569 size_t n = strftime_l(buf, 100, f, &t, __loc_);
4570 char* bb = buf;
4571 char* be = buf + n;
4572 string result;
4573 while (bb != be)
4574 {
4575 if (ct.is(ctype_base::space, *bb))
4576 {
4577 result.push_back(' ');
4578 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4579 ;
4580 continue;
4581 }
4582 char* w = bb;
4583 ios_base::iostate err = ios_base::goodbit;
4584 int i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4585 ct, err, false)
4586 - this->__weeks_;
4587 if (i < 14)
4588 {
4589 result.push_back('%');
4590 if (i < 7)
4591 result.push_back('A');
4592 else
4593 result.push_back('a');
4594 bb = w;
4595 continue;
4596 }
4597 w = bb;
4598 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4599 ct, err, false)
4600 - this->__months_;
4601 if (i < 24)
4602 {
4603 result.push_back('%');
4604 if (i < 12)
4605 result.push_back('B');
4606 else
4607 result.push_back('b');
4608 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4609 result.back() = 'm';
4610 bb = w;
4611 continue;
4612 }
4613 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4614 {
4615 w = bb;
4616 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4617 ct, err, false) - this->__am_pm_;
4618 if (i < 2)
4619 {
4620 result.push_back('%');
4621 result.push_back('p');
4622 bb = w;
4623 continue;
4624 }
4625 }
4626 w = bb;
4627 if (ct.is(ctype_base::digit, *bb))
4628 {
4629 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4630 {
4631 case 6:
4632 result.push_back('%');
4633 result.push_back('w');
4634 break;
4635 case 7:
4636 result.push_back('%');
4637 result.push_back('u');
4638 break;
4639 case 11:
4640 result.push_back('%');
4641 result.push_back('I');
4642 break;
4643 case 12:
4644 result.push_back('%');
4645 result.push_back('m');
4646 break;
4647 case 23:
4648 result.push_back('%');
4649 result.push_back('H');
4650 break;
4651 case 31:
4652 result.push_back('%');
4653 result.push_back('d');
4654 break;
4655 case 55:
4656 result.push_back('%');
4657 result.push_back('M');
4658 break;
4659 case 59:
4660 result.push_back('%');
4661 result.push_back('S');
4662 break;
4663 case 61:
4664 result.push_back('%');
4665 result.push_back('y');
4666 break;
4667 case 364:
4668 result.push_back('%');
4669 result.push_back('j');
4670 break;
4671 case 2061:
4672 result.push_back('%');
4673 result.push_back('Y');
4674 break;
4675 default:
4676 for (; w != bb; ++w)
4677 result.push_back(*w);
4678 break;
4679 }
4680 continue;
4681 }
4682 if (*bb == '%')
4683 {
4684 result.push_back('%');
4685 result.push_back('%');
4686 ++bb;
4687 continue;
4688 }
4689 result.push_back(*bb);
4690 ++bb;
4691 }
4692 return result;
4693}
4694
4695template <>
4696wstring
4697__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4698{
4699 tm t;
4700 t.tm_sec = 59;
4701 t.tm_min = 55;
4702 t.tm_hour = 23;
4703 t.tm_mday = 31;
4704 t.tm_mon = 11;
4705 t.tm_year = 161;
4706 t.tm_wday = 6;
4707 t.tm_yday = 364;
4708 t.tm_isdst = -1;
4709 char buf[100];
4710 char f[3] = {0};
4711 f[0] = '%';
4712 f[1] = fmt;
4713 size_t be = strftime_l(buf, 100, f, &t, __loc_);
4714 wchar_t wbuf[100];
4715 wchar_t* wbb = wbuf;
4716 mbstate_t mb = {0};
4717 const char* bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004718#ifdef _LIBCPP_STABLE_APPLE_ABI
4719 size_t i = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4720#else
4721 size_t i = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4722#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004723 if (i == -1)
4724 __throw_runtime_error("locale not supported");
4725 wchar_t* wbe = wbb + i;
4726 wstring result;
4727 while (wbb != wbe)
4728 {
4729 if (ct.is(ctype_base::space, *wbb))
4730 {
4731 result.push_back(L' ');
4732 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4733 ;
4734 continue;
4735 }
4736 wchar_t* w = wbb;
4737 ios_base::iostate err = ios_base::goodbit;
4738 int i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4739 ct, err, false)
4740 - this->__weeks_;
4741 if (i < 14)
4742 {
4743 result.push_back(L'%');
4744 if (i < 7)
4745 result.push_back(L'A');
4746 else
4747 result.push_back(L'a');
4748 wbb = w;
4749 continue;
4750 }
4751 w = wbb;
4752 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4753 ct, err, false)
4754 - this->__months_;
4755 if (i < 24)
4756 {
4757 result.push_back(L'%');
4758 if (i < 12)
4759 result.push_back(L'B');
4760 else
4761 result.push_back(L'b');
4762 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4763 result.back() = L'm';
4764 wbb = w;
4765 continue;
4766 }
4767 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4768 {
4769 w = wbb;
4770 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4771 ct, err, false) - this->__am_pm_;
4772 if (i < 2)
4773 {
4774 result.push_back(L'%');
4775 result.push_back(L'p');
4776 wbb = w;
4777 continue;
4778 }
4779 }
4780 w = wbb;
4781 if (ct.is(ctype_base::digit, *wbb))
4782 {
4783 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4784 {
4785 case 6:
4786 result.push_back(L'%');
4787 result.push_back(L'w');
4788 break;
4789 case 7:
4790 result.push_back(L'%');
4791 result.push_back(L'u');
4792 break;
4793 case 11:
4794 result.push_back(L'%');
4795 result.push_back(L'I');
4796 break;
4797 case 12:
4798 result.push_back(L'%');
4799 result.push_back(L'm');
4800 break;
4801 case 23:
4802 result.push_back(L'%');
4803 result.push_back(L'H');
4804 break;
4805 case 31:
4806 result.push_back(L'%');
4807 result.push_back(L'd');
4808 break;
4809 case 55:
4810 result.push_back(L'%');
4811 result.push_back(L'M');
4812 break;
4813 case 59:
4814 result.push_back(L'%');
4815 result.push_back(L'S');
4816 break;
4817 case 61:
4818 result.push_back(L'%');
4819 result.push_back(L'y');
4820 break;
4821 case 364:
4822 result.push_back(L'%');
4823 result.push_back(L'j');
4824 break;
4825 case 2061:
4826 result.push_back(L'%');
4827 result.push_back(L'Y');
4828 break;
4829 default:
4830 for (; w != wbb; ++w)
4831 result.push_back(*w);
4832 break;
4833 }
4834 continue;
4835 }
4836 if (ct.narrow(*wbb, 0) == '%')
4837 {
4838 result.push_back(L'%');
4839 result.push_back(L'%');
4840 ++wbb;
4841 continue;
4842 }
4843 result.push_back(*wbb);
4844 ++wbb;
4845 }
4846 return result;
4847}
4848
4849template <>
4850void
4851__time_get_storage<char>::init(const ctype<char>& ct)
4852{
4853 tm t;
4854 char buf[100];
4855 // __weeks_
4856 for (int i = 0; i < 7; ++i)
4857 {
4858 t.tm_wday = i;
4859 strftime_l(buf, 100, "%A", &t, __loc_);
4860 __weeks_[i] = buf;
4861 strftime_l(buf, 100, "%a", &t, __loc_);
4862 __weeks_[i+7] = buf;
4863 }
4864 // __months_
4865 for (int i = 0; i < 12; ++i)
4866 {
4867 t.tm_mon = i;
4868 strftime_l(buf, 100, "%B", &t, __loc_);
4869 __months_[i] = buf;
4870 strftime_l(buf, 100, "%b", &t, __loc_);
4871 __months_[i+12] = buf;
4872 }
4873 // __am_pm_
4874 t.tm_hour = 1;
4875 strftime_l(buf, 100, "%p", &t, __loc_);
4876 __am_pm_[0] = buf;
4877 t.tm_hour = 13;
4878 strftime_l(buf, 100, "%p", &t, __loc_);
4879 __am_pm_[1] = buf;
4880 __c_ = __analyze('c', ct);
4881 __r_ = __analyze('r', ct);
4882 __x_ = __analyze('x', ct);
4883 __X_ = __analyze('X', ct);
4884}
4885
4886template <>
4887void
4888__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4889{
4890 tm t = {0};
4891 char buf[100];
4892 size_t be;
4893 wchar_t wbuf[100];
4894 wchar_t* wbe;
4895 mbstate_t mb = {0};
4896 // __weeks_
4897 for (int i = 0; i < 7; ++i)
4898 {
4899 t.tm_wday = i;
4900 be = strftime_l(buf, 100, "%A", &t, __loc_);
4901 mb = mbstate_t();
4902 const char* bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004903#ifdef _LIBCPP_STABLE_APPLE_ABI
4904 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4905#else
4906 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4907#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004908 if (j == -1)
4909 __throw_runtime_error("locale not supported");
4910 wbe = wbuf + j;
4911 __weeks_[i].assign(wbuf, wbe);
4912 be = strftime_l(buf, 100, "%a", &t, __loc_);
4913 mb = mbstate_t();
4914 bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004915#ifdef _LIBCPP_STABLE_APPLE_ABI
4916 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4917#else
4918 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4919#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004920 if (j == -1)
4921 __throw_runtime_error("locale not supported");
4922 wbe = wbuf + j;
4923 __weeks_[i+7].assign(wbuf, wbe);
4924 }
4925 // __months_
4926 for (int i = 0; i < 12; ++i)
4927 {
4928 t.tm_mon = i;
4929 be = strftime_l(buf, 100, "%B", &t, __loc_);
4930 mb = mbstate_t();
4931 const char* bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004932#ifdef _LIBCPP_STABLE_APPLE_ABI
4933 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4934#else
4935 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4936#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004937 if (j == -1)
4938 __throw_runtime_error("locale not supported");
4939 wbe = wbuf + j;
4940 __months_[i].assign(wbuf, wbe);
4941 be = strftime_l(buf, 100, "%b", &t, __loc_);
4942 mb = mbstate_t();
4943 bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004944#ifdef _LIBCPP_STABLE_APPLE_ABI
4945 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4946#else
4947 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4948#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004949 if (j == -1)
4950 __throw_runtime_error("locale not supported");
4951 wbe = wbuf + j;
4952 __months_[i+12].assign(wbuf, wbe);
4953 }
4954 // __am_pm_
4955 t.tm_hour = 1;
4956 be = strftime_l(buf, 100, "%p", &t, __loc_);
4957 mb = mbstate_t();
4958 const char* bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004959#ifdef _LIBCPP_STABLE_APPLE_ABI
4960 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4961#else
4962 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4963#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004964 if (j == -1)
4965 __throw_runtime_error("locale not supported");
4966 wbe = wbuf + j;
4967 __am_pm_[0].assign(wbuf, wbe);
4968 t.tm_hour = 13;
4969 be = strftime_l(buf, 100, "%p", &t, __loc_);
4970 mb = mbstate_t();
4971 bb = buf;
Sean Huntf3907e62011-07-15 05:40:33 +00004972#ifdef _LIBCPP_STABLE_APPLE_ABI
4973 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4974#else
4975 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4976#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004977 if (j == -1)
4978 __throw_runtime_error("locale not supported");
4979 wbe = wbuf + j;
4980 __am_pm_[1].assign(wbuf, wbe);
4981 __c_ = __analyze('c', ct);
4982 __r_ = __analyze('r', ct);
4983 __x_ = __analyze('x', ct);
4984 __X_ = __analyze('X', ct);
4985}
4986
4987template <class CharT>
4988struct _LIBCPP_HIDDEN __time_get_temp
4989 : public ctype_byname<CharT>
4990{
4991 explicit __time_get_temp(const char* nm)
4992 : ctype_byname<CharT>(nm, 1) {}
4993 explicit __time_get_temp(const string& nm)
4994 : ctype_byname<CharT>(nm, 1) {}
4995};
4996
4997template <>
4998__time_get_storage<char>::__time_get_storage(const char* __nm)
4999 : __time_get(__nm)
5000{
5001 const __time_get_temp<char> ct(__nm);
5002 init(ct);
5003}
5004
5005template <>
5006__time_get_storage<char>::__time_get_storage(const string& __nm)
5007 : __time_get(__nm)
5008{
5009 const __time_get_temp<char> ct(__nm);
5010 init(ct);
5011}
5012
5013template <>
5014__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5015 : __time_get(__nm)
5016{
5017 const __time_get_temp<wchar_t> ct(__nm);
5018 init(ct);
5019}
5020
5021template <>
5022__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5023 : __time_get(__nm)
5024{
5025 const __time_get_temp<wchar_t> ct(__nm);
5026 init(ct);
5027}
5028
5029template <>
5030time_base::dateorder
5031__time_get_storage<char>::__do_date_order() const
5032{
5033 unsigned i;
5034 for (i = 0; i < __x_.size(); ++i)
5035 if (__x_[i] == '%')
5036 break;
5037 ++i;
5038 switch (__x_[i])
5039 {
5040 case 'y':
5041 case 'Y':
5042 for (++i; i < __x_.size(); ++i)
5043 if (__x_[i] == '%')
5044 break;
5045 if (i == __x_.size())
5046 break;
5047 ++i;
5048 switch (__x_[i])
5049 {
5050 case 'm':
5051 for (++i; i < __x_.size(); ++i)
5052 if (__x_[i] == '%')
5053 break;
5054 if (i == __x_.size())
5055 break;
5056 ++i;
5057 if (__x_[i] == 'd')
5058 return time_base::ymd;
5059 break;
5060 case 'd':
5061 for (++i; i < __x_.size(); ++i)
5062 if (__x_[i] == '%')
5063 break;
5064 if (i == __x_.size())
5065 break;
5066 ++i;
5067 if (__x_[i] == 'm')
5068 return time_base::ydm;
5069 break;
5070 }
5071 break;
5072 case 'm':
5073 for (++i; i < __x_.size(); ++i)
5074 if (__x_[i] == '%')
5075 break;
5076 if (i == __x_.size())
5077 break;
5078 ++i;
5079 if (__x_[i] == 'd')
5080 {
5081 for (++i; i < __x_.size(); ++i)
5082 if (__x_[i] == '%')
5083 break;
5084 if (i == __x_.size())
5085 break;
5086 ++i;
5087 if (__x_[i] == 'y' || __x_[i] == 'Y')
5088 return time_base::mdy;
5089 break;
5090 }
5091 break;
5092 case 'd':
5093 for (++i; i < __x_.size(); ++i)
5094 if (__x_[i] == '%')
5095 break;
5096 if (i == __x_.size())
5097 break;
5098 ++i;
5099 if (__x_[i] == 'm')
5100 {
5101 for (++i; i < __x_.size(); ++i)
5102 if (__x_[i] == '%')
5103 break;
5104 if (i == __x_.size())
5105 break;
5106 ++i;
5107 if (__x_[i] == 'y' || __x_[i] == 'Y')
5108 return time_base::dmy;
5109 break;
5110 }
5111 break;
5112 }
5113 return time_base::no_order;
5114}
5115
5116template <>
5117time_base::dateorder
5118__time_get_storage<wchar_t>::__do_date_order() const
5119{
5120 unsigned i;
5121 for (i = 0; i < __x_.size(); ++i)
5122 if (__x_[i] == L'%')
5123 break;
5124 ++i;
5125 switch (__x_[i])
5126 {
5127 case L'y':
5128 case L'Y':
5129 for (++i; i < __x_.size(); ++i)
5130 if (__x_[i] == L'%')
5131 break;
5132 if (i == __x_.size())
5133 break;
5134 ++i;
5135 switch (__x_[i])
5136 {
5137 case L'm':
5138 for (++i; i < __x_.size(); ++i)
5139 if (__x_[i] == L'%')
5140 break;
5141 if (i == __x_.size())
5142 break;
5143 ++i;
5144 if (__x_[i] == L'd')
5145 return time_base::ymd;
5146 break;
5147 case L'd':
5148 for (++i; i < __x_.size(); ++i)
5149 if (__x_[i] == L'%')
5150 break;
5151 if (i == __x_.size())
5152 break;
5153 ++i;
5154 if (__x_[i] == L'm')
5155 return time_base::ydm;
5156 break;
5157 }
5158 break;
5159 case L'm':
5160 for (++i; i < __x_.size(); ++i)
5161 if (__x_[i] == L'%')
5162 break;
5163 if (i == __x_.size())
5164 break;
5165 ++i;
5166 if (__x_[i] == L'd')
5167 {
5168 for (++i; i < __x_.size(); ++i)
5169 if (__x_[i] == L'%')
5170 break;
5171 if (i == __x_.size())
5172 break;
5173 ++i;
5174 if (__x_[i] == L'y' || __x_[i] == L'Y')
5175 return time_base::mdy;
5176 break;
5177 }
5178 break;
5179 case L'd':
5180 for (++i; i < __x_.size(); ++i)
5181 if (__x_[i] == L'%')
5182 break;
5183 if (i == __x_.size())
5184 break;
5185 ++i;
5186 if (__x_[i] == L'm')
5187 {
5188 for (++i; i < __x_.size(); ++i)
5189 if (__x_[i] == L'%')
5190 break;
5191 if (i == __x_.size())
5192 break;
5193 ++i;
5194 if (__x_[i] == L'y' || __x_[i] == L'Y')
5195 return time_base::dmy;
5196 break;
5197 }
5198 break;
5199 }
5200 return time_base::no_order;
5201}
5202
5203// time_put
5204
5205__time_put::__time_put(const char* nm)
5206 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5207{
Howard Hinnantd4444702010-08-11 17:04:31 +00005208#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005209 if (__loc_ == 0)
5210 throw runtime_error("time_put_byname"
5211 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005212#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005213}
5214
5215__time_put::__time_put(const string& nm)
5216 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5217{
Howard Hinnantd4444702010-08-11 17:04:31 +00005218#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005219 if (__loc_ == 0)
5220 throw runtime_error("time_put_byname"
5221 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005222#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005223}
5224
5225__time_put::~__time_put()
5226{
5227 if (__loc_)
5228 freelocale(__loc_);
5229}
5230
5231void
5232__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5233 char __fmt, char __mod) const
5234{
5235 char fmt[] = {'%', __fmt, __mod, 0};
5236 if (__mod != 0)
5237 swap(fmt[1], fmt[2]);
5238 size_t n = strftime_l(__nb, __ne-__nb, fmt, __tm, __loc_);
5239 __ne = __nb + n;
5240}
5241
5242void
5243__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5244 char __fmt, char __mod) const
5245{
5246 char __nar[100];
5247 char* __ne = __nar + 100;
5248 __do_put(__nar, __ne, __tm, __fmt, __mod);
5249 mbstate_t mb = {0};
5250 const char* __nb = __nar;
Sean Huntf3907e62011-07-15 05:40:33 +00005251#ifdef _LIBCPP_STABLE_APPLE_ABI
5252 size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5253#else
5254 size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5255#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005256 if (j == -1)
5257 __throw_runtime_error("locale not supported");
5258 __we = __wb + j;
5259}
5260
5261// moneypunct_byname
5262
5263static
5264void
5265__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5266{
5267 const char sign = static_cast<char>(money_base::sign);
5268 const char space = static_cast<char>(money_base::space);
5269 const char none = static_cast<char>(money_base::none);
5270 const char symbol = static_cast<char>(money_base::symbol);
5271 const char value = static_cast<char>(money_base::value);
5272 switch (cs_precedes)
5273 {
5274 case 0:
5275 switch (sign_posn)
5276 {
5277 case 0:
5278 pat.field[0] = sign;
5279 pat.field[1] = value;
5280 pat.field[3] = symbol;
5281 switch (sep_by_space)
5282 {
5283 case 0:
5284 pat.field[2] = none;
5285 return;
5286 case 1:
5287 case 2:
5288 pat.field[2] = space;
5289 return;
5290 default:
5291 break;
5292 }
5293 break;
5294 case 1:
5295 pat.field[0] = sign;
5296 pat.field[3] = symbol;
5297 switch (sep_by_space)
5298 {
5299 case 0:
5300 pat.field[1] = value;
5301 pat.field[2] = none;
5302 return;
5303 case 1:
5304 pat.field[1] = value;
5305 pat.field[2] = space;
5306 return;
5307 case 2:
5308 pat.field[1] = space;
5309 pat.field[2] = value;
5310 return;
5311 default:
5312 break;
5313 }
5314 break;
5315 case 2:
5316 pat.field[0] = value;
5317 pat.field[3] = sign;
5318 switch (sep_by_space)
5319 {
5320 case 0:
5321 pat.field[1] = none;
5322 pat.field[2] = symbol;
5323 return;
5324 case 1:
5325 pat.field[1] = space;
5326 pat.field[2] = symbol;
5327 return;
5328 case 2:
5329 pat.field[1] = symbol;
5330 pat.field[2] = space;
5331 return;
5332 default:
5333 break;
5334 }
5335 break;
5336 case 3:
5337 pat.field[0] = value;
5338 pat.field[3] = symbol;
5339 switch (sep_by_space)
5340 {
5341 case 0:
5342 pat.field[1] = none;
5343 pat.field[2] = sign;
5344 return;
5345 case 1:
5346 pat.field[1] = space;
5347 pat.field[2] = sign;
5348 return;
5349 case 2:
5350 pat.field[1] = sign;
5351 pat.field[2] = space;
5352 return;
5353 default:
5354 break;
5355 }
5356 break;
5357 case 4:
5358 pat.field[0] = value;
5359 pat.field[3] = sign;
5360 switch (sep_by_space)
5361 {
5362 case 0:
5363 pat.field[1] = none;
5364 pat.field[2] = symbol;
5365 return;
5366 case 1:
5367 pat.field[1] = space;
5368 pat.field[2] = symbol;
5369 return;
5370 case 2:
5371 pat.field[1] = symbol;
5372 pat.field[2] = space;
5373 return;
5374 default:
5375 break;
5376 }
5377 break;
5378 default:
5379 break;
5380 }
5381 break;
5382 case 1:
5383 switch (sign_posn)
5384 {
5385 case 0:
5386 pat.field[0] = sign;
5387 pat.field[1] = symbol;
5388 pat.field[3] = value;
5389 switch (sep_by_space)
5390 {
5391 case 0:
5392 pat.field[2] = none;
5393 return;
5394 case 1:
5395 case 2:
5396 pat.field[2] = space;
5397 return;
5398 default:
5399 break;
5400 }
5401 break;
5402 case 1:
5403 pat.field[0] = sign;
5404 pat.field[3] = value;
5405 switch (sep_by_space)
5406 {
5407 case 0:
5408 pat.field[1] = symbol;
5409 pat.field[2] = none;
5410 return;
5411 case 1:
5412 pat.field[1] = symbol;
5413 pat.field[2] = space;
5414 return;
5415 case 2:
5416 pat.field[1] = space;
5417 pat.field[2] = symbol;
5418 return;
5419 default:
5420 break;
5421 }
5422 break;
5423 case 2:
5424 pat.field[0] = symbol;
5425 pat.field[3] = sign;
5426 switch (sep_by_space)
5427 {
5428 case 0:
5429 pat.field[1] = none;
5430 pat.field[2] = value;
5431 return;
5432 case 1:
5433 pat.field[1] = space;
5434 pat.field[2] = value;
5435 return;
5436 case 2:
5437 pat.field[1] = value;
5438 pat.field[2] = space;
5439 return;
5440 default:
5441 break;
5442 }
5443 break;
5444 case 3:
5445 pat.field[0] = sign;
5446 pat.field[3] = value;
5447 switch (sep_by_space)
5448 {
5449 case 0:
5450 pat.field[1] = symbol;
5451 pat.field[2] = none;
5452 return;
5453 case 1:
5454 pat.field[1] = symbol;
5455 pat.field[2] = space;
5456 return;
5457 case 2:
5458 pat.field[1] = space;
5459 pat.field[2] = symbol;
5460 return;
5461 default:
5462 break;
5463 }
5464 break;
5465 case 4:
5466 pat.field[0] = symbol;
5467 pat.field[3] = value;
5468 switch (sep_by_space)
5469 {
5470 case 0:
5471 pat.field[1] = sign;
5472 pat.field[2] = none;
5473 return;
5474 case 1:
5475 pat.field[1] = sign;
5476 pat.field[2] = space;
5477 return;
5478 case 2:
5479 pat.field[1] = space;
5480 pat.field[2] = sign;
5481 return;
5482 default:
5483 break;
5484 }
5485 break;
5486 default:
5487 break;
5488 }
5489 break;
5490 default:
5491 break;
5492 }
5493 pat.field[0] = symbol;
5494 pat.field[1] = sign;
5495 pat.field[2] = none;
5496 pat.field[3] = value;
5497}
5498
5499template<>
5500void
5501moneypunct_byname<char, false>::init(const char* nm)
5502{
5503 typedef moneypunct<char, false> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005504 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005505#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005506 if (loc == 0)
5507 throw runtime_error("moneypunct_byname"
5508 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005509#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005510#ifdef _LIBCPP_STABLE_APPLE_ABI
5511 lconv* lc = localeconv_l(loc.get());
5512#else
5513 lconv* lc = __localeconv_l(loc.get());
5514#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005515 if (*lc->mon_decimal_point)
5516 __decimal_point_ = *lc->mon_decimal_point;
5517 else
5518 __decimal_point_ = base::do_decimal_point();
5519 if (*lc->mon_thousands_sep)
5520 __thousands_sep_ = *lc->mon_thousands_sep;
5521 else
5522 __thousands_sep_ = base::do_thousands_sep();
5523 __grouping_ = lc->mon_grouping;
5524 __curr_symbol_ = lc->currency_symbol;
5525 if (lc->frac_digits != CHAR_MAX)
5526 __frac_digits_ = lc->frac_digits;
5527 else
5528 __frac_digits_ = base::do_frac_digits();
5529 if (lc->p_sign_posn == 0)
5530 __positive_sign_ = "()";
5531 else
5532 __positive_sign_ = lc->positive_sign;
5533 if (lc->n_sign_posn == 0)
5534 __negative_sign_ = "()";
5535 else
5536 __negative_sign_ = lc->negative_sign;
5537 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5538 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5539}
5540
5541template<>
5542void
5543moneypunct_byname<char, true>::init(const char* nm)
5544{
5545 typedef moneypunct<char, true> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005546 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005547#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005548 if (loc == 0)
5549 throw runtime_error("moneypunct_byname"
5550 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005551#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005552#ifdef _LIBCPP_STABLE_APPLE_ABI
5553 lconv* lc = localeconv_l(loc.get());
5554#else
5555 lconv* lc = __localeconv_l(loc.get());
5556#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005557 if (*lc->mon_decimal_point)
5558 __decimal_point_ = *lc->mon_decimal_point;
5559 else
5560 __decimal_point_ = base::do_decimal_point();
5561 if (*lc->mon_thousands_sep)
5562 __thousands_sep_ = *lc->mon_thousands_sep;
5563 else
5564 __thousands_sep_ = base::do_thousands_sep();
5565 __grouping_ = lc->mon_grouping;
5566 __curr_symbol_ = lc->int_curr_symbol;
5567 if (lc->int_frac_digits != CHAR_MAX)
5568 __frac_digits_ = lc->int_frac_digits;
5569 else
5570 __frac_digits_ = base::do_frac_digits();
5571 if (lc->int_p_sign_posn == 0)
5572 __positive_sign_ = "()";
5573 else
5574 __positive_sign_ = lc->positive_sign;
5575 if (lc->int_n_sign_posn == 0)
5576 __negative_sign_ = "()";
5577 else
5578 __negative_sign_ = lc->negative_sign;
5579 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5580 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5581}
5582
5583template<>
5584void
5585moneypunct_byname<wchar_t, false>::init(const char* nm)
5586{
5587 typedef moneypunct<wchar_t, false> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005588 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005589#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005590 if (loc == 0)
5591 throw runtime_error("moneypunct_byname"
5592 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005593#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005594#ifdef _LIBCPP_STABLE_APPLE_ABI
5595 lconv* lc = localeconv_l(loc.get());
5596#else
5597 lconv* lc = __localeconv_l(loc.get());
5598#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005599 if (*lc->mon_decimal_point)
5600 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5601 else
5602 __decimal_point_ = base::do_decimal_point();
5603 if (*lc->mon_thousands_sep)
5604 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5605 else
5606 __thousands_sep_ = base::do_thousands_sep();
5607 __grouping_ = lc->mon_grouping;
5608 wchar_t wbuf[100];
5609 mbstate_t mb = {0};
5610 const char* bb = lc->currency_symbol;
Sean Huntf3907e62011-07-15 05:40:33 +00005611#ifdef _LIBCPP_STABLE_APPLE_ABI
5612 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5613#else
5614 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5615#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005616 if (j == -1)
5617 __throw_runtime_error("locale not supported");
5618 wchar_t* wbe = wbuf + j;
5619 __curr_symbol_.assign(wbuf, wbe);
5620 if (lc->frac_digits != CHAR_MAX)
5621 __frac_digits_ = lc->frac_digits;
5622 else
5623 __frac_digits_ = base::do_frac_digits();
5624 if (lc->p_sign_posn == 0)
5625 __positive_sign_ = L"()";
5626 else
5627 {
5628 mb = mbstate_t();
5629 bb = lc->positive_sign;
Sean Huntf3907e62011-07-15 05:40:33 +00005630#ifdef _LIBCPP_STABLE_APPLE_ABI
5631 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5632#else
5633 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5634#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005635 if (j == -1)
5636 __throw_runtime_error("locale not supported");
5637 wbe = wbuf + j;
5638 __positive_sign_.assign(wbuf, wbe);
5639 }
5640 if (lc->n_sign_posn == 0)
5641 __negative_sign_ = L"()";
5642 else
5643 {
5644 mb = mbstate_t();
5645 bb = lc->negative_sign;
Sean Huntf3907e62011-07-15 05:40:33 +00005646#ifdef _LIBCPP_STABLE_APPLE_ABI
5647 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5648#else
5649 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5650#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005651 if (j == -1)
5652 __throw_runtime_error("locale not supported");
5653 wbe = wbuf + j;
5654 __negative_sign_.assign(wbuf, wbe);
5655 }
5656 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5657 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5658}
5659
5660template<>
5661void
5662moneypunct_byname<wchar_t, true>::init(const char* nm)
5663{
5664 typedef moneypunct<wchar_t, true> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005665 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005666#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005667 if (loc == 0)
5668 throw runtime_error("moneypunct_byname"
5669 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005670#endif // _LIBCPP_NO_EXCEPTIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005671#ifdef _LIBCPP_STABLE_APPLE_ABI
5672 lconv* lc = localeconv_l(loc.get());
5673#else
5674 lconv* lc = __localeconv_l(loc.get());
5675#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005676 if (*lc->mon_decimal_point)
5677 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5678 else
5679 __decimal_point_ = base::do_decimal_point();
5680 if (*lc->mon_thousands_sep)
5681 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5682 else
5683 __thousands_sep_ = base::do_thousands_sep();
5684 __grouping_ = lc->mon_grouping;
5685 wchar_t wbuf[100];
5686 mbstate_t mb = {0};
5687 const char* bb = lc->int_curr_symbol;
Sean Huntf3907e62011-07-15 05:40:33 +00005688#ifdef _LIBCPP_STABLE_APPLE_ABI
5689 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5690#else
5691 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5692#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005693 if (j == -1)
5694 __throw_runtime_error("locale not supported");
5695 wchar_t* wbe = wbuf + j;
5696 __curr_symbol_.assign(wbuf, wbe);
5697 if (lc->int_frac_digits != CHAR_MAX)
5698 __frac_digits_ = lc->int_frac_digits;
5699 else
5700 __frac_digits_ = base::do_frac_digits();
5701 if (lc->int_p_sign_posn == 0)
5702 __positive_sign_ = L"()";
5703 else
5704 {
5705 mb = mbstate_t();
5706 bb = lc->positive_sign;
Sean Huntf3907e62011-07-15 05:40:33 +00005707#ifdef _LIBCPP_STABLE_APPLE_ABI
5708 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5709#else
5710 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5711#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005712 if (j == -1)
5713 __throw_runtime_error("locale not supported");
5714 wbe = wbuf + j;
5715 __positive_sign_.assign(wbuf, wbe);
5716 }
5717 if (lc->int_n_sign_posn == 0)
5718 __negative_sign_ = L"()";
5719 else
5720 {
5721 mb = mbstate_t();
5722 bb = lc->negative_sign;
Sean Huntf3907e62011-07-15 05:40:33 +00005723#ifdef _LIBCPP_STABLE_APPLE_ABI
5724 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5725#else
5726 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5727#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005728 if (j == -1)
5729 __throw_runtime_error("locale not supported");
5730 wbe = wbuf + j;
5731 __negative_sign_.assign(wbuf, wbe);
5732 }
5733 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5734 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5735}
5736
5737void __do_nothing(void*) {}
5738
5739void __throw_runtime_error(const char* msg)
5740{
Howard Hinnantd4444702010-08-11 17:04:31 +00005741#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005742 throw runtime_error(msg);
Howard Hinnantd4444702010-08-11 17:04:31 +00005743#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005744}
5745
5746template class collate<char>;
5747template class collate<wchar_t>;
5748
5749template class num_get<char>;
5750template class num_get<wchar_t>;
5751
5752template class __num_get<char>;
5753template class __num_get<wchar_t>;
5754
5755template class num_put<char>;
5756template class num_put<wchar_t>;
5757
5758template class __num_put<char>;
5759template class __num_put<wchar_t>;
5760
5761template class time_get<char>;
5762template class time_get<wchar_t>;
5763
5764template class time_get_byname<char>;
5765template class time_get_byname<wchar_t>;
5766
5767template class time_put<char>;
5768template class time_put<wchar_t>;
5769
5770template class time_put_byname<char>;
5771template class time_put_byname<wchar_t>;
5772
5773template class moneypunct<char, false>;
5774template class moneypunct<char, true>;
5775template class moneypunct<wchar_t, false>;
5776template class moneypunct<wchar_t, true>;
5777
5778template class moneypunct_byname<char, false>;
5779template class moneypunct_byname<char, true>;
5780template class moneypunct_byname<wchar_t, false>;
5781template class moneypunct_byname<wchar_t, true>;
5782
5783template class money_get<char>;
5784template class money_get<wchar_t>;
5785
5786template class __money_get<char>;
5787template class __money_get<wchar_t>;
5788
5789template class money_put<char>;
5790template class money_put<wchar_t>;
5791
5792template class __money_put<char>;
5793template class __money_put<wchar_t>;
5794
5795template class messages<char>;
5796template class messages<wchar_t>;
5797
5798template class messages_byname<char>;
5799template class messages_byname<wchar_t>;
5800
5801template class codecvt_byname<char, char, mbstate_t>;
5802template class codecvt_byname<wchar_t, char, mbstate_t>;
5803template class codecvt_byname<char16_t, char, mbstate_t>;
5804template class codecvt_byname<char32_t, char, mbstate_t>;
5805
5806template class __vector_base_common<true>;
5807
5808_LIBCPP_END_NAMESPACE_STD