blob: 2636e1774a44f4b61be52631e462708e7b3032bb [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001//===------------------------- locale.cpp ---------------------------------===//
2//
Howard Hinnantc566dc32010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00004//
Howard Hinnantee11c312010-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 Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "string"
11#include "locale"
Howard Hinnant7282c5a2010-05-30 21:39:41 +000012#include "codecvt"
Howard Hinnantc51e1022010-05-11 19:42:16 +000013#include "vector"
14#include "algorithm"
15#include "algorithm"
16#include "typeinfo"
Howard Hinnantbf6c0b42011-06-30 14:21:55 +000017#include "type_traits"
Howard Hinnantc51e1022010-05-11 19:42:16 +000018#include "clocale"
19#include "cstring"
20#include "cwctype"
21#include "__sso_allocator"
Howard Hinnantc51e1022010-05-11 19:42:16 +000022#include <langinfo.h>
23#include <stdlib.h>
24
Alexis Hunt1adf2aa2011-07-15 05:40:33 +000025#ifdef _LIBCPP_STABLE_APPLE_ABI
Howard Hinnantbf6c0b42011-06-30 14:21:55 +000026namespace {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +000027 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
Howard Hinnantbf6c0b42011-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 }
Alexis Hunt1adf2aa2011-07-15 05:40:33 +000033}
Howard Hinnantbf6c0b42011-06-30 14:21:55 +000034#endif
Howard Hinnantbf6c0b42011-06-30 14:21:55 +000035
Howard Hinnantc51e1022010-05-11 19:42:16 +000036_LIBCPP_BEGIN_NAMESPACE_STD
37
Alexis Hunt5a4dd562011-07-09 01:09:31 +000038#ifndef _LIBCPP_APPLE_STABLE_ABI
Alexis Hunt92b0c812011-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}
Alexis Hunt5a4dd562011-07-09 01:09:31 +000050#endif // _LIBCPP_APPLE_STABLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +000051
Howard Hinnantc51e1022010-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 Hinnantb1ad5a82011-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 Hinnantc51e1022010-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 Hinnantb1ad5a82011-06-30 21:18:19 +0000150 install(&make<_VSTD::messages<char> >(1));
151 install(&make<_VSTD::messages<wchar_t> >(1));
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000159#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160 try
161 {
Howard Hinnantffb308e2010-08-22 00:03:27 +0000162#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000187#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000196#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000217#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000218 try
219 {
Howard Hinnantffb308e2010-08-22 00:03:27 +0000220#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000259#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000268#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000288#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 try
290 {
Howard Hinnantffb308e2010-08-22 00:03:27 +0000291#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 if (c & locale::collate)
293 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000294 install_from<_VSTD::collate<char> >(one);
295 install_from<_VSTD::collate<wchar_t> >(one);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000296 }
297 if (c & locale::ctype)
298 {
Howard Hinnantb1ad5a82011-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 Hinnantc51e1022010-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 Hinnantb1ad5a82011-06-30 21:18:19 +0000335 install_from<_VSTD::messages<char> >(one);
336 install_from<_VSTD::messages<wchar_t> >(one);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337 }
Howard Hinnant72f73582010-08-11 17:04:31 +0000338#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000347#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000385#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 if (!has_facet(id))
387 throw bad_cast();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000388#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant7c9e5732011-05-31 15:34:58 +0000428locale::locale() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000429 : __locale_(__global().__locale_)
430{
431 __locale_->__add_shared();
432}
433
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000434locale::locale(const locale& l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000435 : __locale_(l.__locale_)
436{
437 __locale_->__add_shared();
438}
439
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000440locale::~locale()
Howard Hinnantc51e1022010-05-11 19:42:16 +0000441{
442 __locale_->__release_shared();
443}
444
445const locale&
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000446locale::operator=(const locale& other) _NOEXCEPT
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000455#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000456 : __locale_(name ? new __imp(name)
457 : throw runtime_error("locale constructed with null"))
Howard Hinnantffb308e2010-08-22 00:03:27 +0000458#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant72f73582010-08-11 17:04:31 +0000459 : __locale_(new __imp(name))
460#endif
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000472#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473 : __locale_(name ? new __imp(*other.__locale_, name, c)
474 : throw runtime_error("locale constructed with null"))
Howard Hinnantffb308e2010-08-22 00:03:27 +0000475#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant72f73582010-08-11 17:04:31 +0000476 : __locale_(new __imp(*other.__locale_, name, c))
477#endif
Howard Hinnantc51e1022010-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 Hinnant719bda32011-05-28 14:41:13 +0000547locale::facet::__on_zero_shared() _NOEXCEPT
Howard Hinnantc51e1022010-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 Hinnant155c2af2010-05-24 17:49:41 +0000585 __id_ = __sync_add_and_fetch(&__next_id, 1);
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000598#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000605#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000609#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000646#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000650#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000657#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000661#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-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{
Alexis Hunt92b0c812011-07-09 00:56:23 +0000703 return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
Howard Hinnantc51e1022010-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)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000710 *vec = static_cast<mask>(isascii(*low) ?
711 ctype<char>::classic_table()[*low] : 0);
Howard Hinnantc51e1022010-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)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000719 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
Howard Hinnantc51e1022010-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)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000728 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000729 break;
730 return low;
731}
732
733wchar_t
734ctype<wchar_t>::do_toupper(char_type c) const
735{
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000736#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000737 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000738#else
739 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
740#endif
Howard Hinnantc51e1022010-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)
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000747#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000748 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
749 : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000750#else
751 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
752#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000753 return low;
754}
755
756wchar_t
757ctype<wchar_t>::do_tolower(char_type c) const
758{
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000759#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000760 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000761#else
762 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
763#endif
Howard Hinnantc51e1022010-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)
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000770#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000771 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
772 : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000773#else
774 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
775#endif
Howard Hinnantc51e1022010-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{
Alexis Hunt92b0c812011-07-09 00:56:23 +0000821 if (__tab_ == 0)
822 __tab_ = classic_table();
Howard Hinnantc51e1022010-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{
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000834#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000835 return isascii(c) ? __classic_upper_table()[c] : c;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000836#else
837 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
838#endif
Howard Hinnantc51e1022010-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)
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000845#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000846 *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000847#else
Howard Hinnant390fc292011-07-09 19:47:01 +0000848 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000849#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000850 return low;
851}
852
853char
854ctype<char>::do_tolower(char_type c) const
855{
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000856#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000857 return isascii(c) ? __classic_lower_table()[c] : c;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000858#else
859 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
860#endif
Howard Hinnantc51e1022010-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)
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000867#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000868 *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000869#else
Howard Hinnant390fc292011-07-09 19:47:01 +0000870 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000871#endif
Howard Hinnantc51e1022010-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 Hinnant7c9e5732011-05-31 15:34:58 +0000909ctype<char>::classic_table() _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910{
Michael J. Spencer8d8164e2010-12-10 19:47:54 +0000911#ifdef __APPLE__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000912 return _DefaultRuneLocale.__runetype;
Alexis Hunt92b0c812011-07-09 00:56:23 +0000913#elif defined(__GLIBC__)
914 return __cloc()->__ctype_b;
915// This is assumed to be safe.
916#else
917 return NULL;
918#endif
919}
920
Howard Hinnant390fc292011-07-09 19:47:01 +0000921#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt92b0c812011-07-09 00:56:23 +0000922const int*
923ctype<char>::__classic_lower_table() _NOEXCEPT
924{
925#ifdef __APPLE__
926 return _DefaultRuneLocale.__maplower;
927#elif defined(__GLIBC__)
928 return __cloc()->__ctype_tolower;
929#else
930 return NULL;
931#endif
932}
933
934const int*
935ctype<char>::__classic_upper_table() _NOEXCEPT
936{
937#ifdef __APPLE__
938 return _DefaultRuneLocale.__mapupper;
939#elif defined(__GLIBC__)
940 return __cloc()->__ctype_toupper;
Michael J. Spencer8d8164e2010-12-10 19:47:54 +0000941#else
942 return NULL;
943#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000944}
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000945#endif // _LIBCPP_APPLE_STABLE_ABI
Howard Hinnantc51e1022010-05-11 19:42:16 +0000946
947// template <> class ctype_byname<char>
948
949ctype_byname<char>::ctype_byname(const char* name, size_t refs)
950 : ctype<char>(0, false, refs),
951 __l(newlocale(LC_ALL_MASK, name, 0))
952{
Howard Hinnant72f73582010-08-11 17:04:31 +0000953#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000954 if (__l == 0)
955 throw runtime_error("ctype_byname<char>::ctype_byname"
956 " failed to construct for " + string(name));
Howard Hinnantffb308e2010-08-22 00:03:27 +0000957#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000958}
959
960ctype_byname<char>::ctype_byname(const string& name, size_t refs)
961 : ctype<char>(0, false, refs),
962 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
963{
Howard Hinnant72f73582010-08-11 17:04:31 +0000964#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000965 if (__l == 0)
966 throw runtime_error("ctype_byname<char>::ctype_byname"
967 " failed to construct for " + name);
Howard Hinnantffb308e2010-08-22 00:03:27 +0000968#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000969}
970
971ctype_byname<char>::~ctype_byname()
972{
973 freelocale(__l);
974}
975
976char
977ctype_byname<char>::do_toupper(char_type c) const
978{
979 return toupper_l(c, __l);
980}
981
982const char*
983ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
984{
985 for (; low != high; ++low)
986 *low = toupper_l(*low, __l);
987 return low;
988}
989
990char
991ctype_byname<char>::do_tolower(char_type c) const
992{
993 return tolower_l(c, __l);
994}
995
996const char*
997ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
998{
999 for (; low != high; ++low)
1000 *low = tolower_l(*low, __l);
1001 return low;
1002}
1003
1004// template <> class ctype_byname<wchar_t>
1005
1006ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1007 : ctype<wchar_t>(refs),
1008 __l(newlocale(LC_ALL_MASK, name, 0))
1009{
Howard Hinnant72f73582010-08-11 17:04:31 +00001010#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001011 if (__l == 0)
1012 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1013 " failed to construct for " + string(name));
Howard Hinnantffb308e2010-08-22 00:03:27 +00001014#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001015}
1016
1017ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1018 : ctype<wchar_t>(refs),
1019 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1020{
Howard Hinnant72f73582010-08-11 17:04:31 +00001021#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001022 if (__l == 0)
1023 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1024 " failed to construct for " + name);
Howard Hinnantffb308e2010-08-22 00:03:27 +00001025#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001026}
1027
1028ctype_byname<wchar_t>::~ctype_byname()
1029{
1030 freelocale(__l);
1031}
1032
1033bool
1034ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1035{
Alexis Huntc2017f12011-07-09 03:40:04 +00001036#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantc51e1022010-05-11 19:42:16 +00001037 return static_cast<bool>(iswctype_l(c, m, __l));
Alexis Huntc2017f12011-07-09 03:40:04 +00001038#else
1039 if (m & space && !iswspace_l(c, __l)) return false;
1040 if (m & print && !iswprint_l(c, __l)) return false;
1041 if (m & cntrl && !iswcntrl_l(c, __l)) return false;
1042 if (m & upper && !iswupper_l(c, __l)) return false;
1043 if (m & lower && !iswlower_l(c, __l)) return false;
1044 if (m & alpha && !iswalpha_l(c, __l)) return false;
1045 if (m & digit && !iswdigit_l(c, __l)) return false;
1046 if (m & punct && !iswpunct_l(c, __l)) return false;
1047 if (m & xdigit && !iswxdigit_l(c, __l)) return false;
1048 if (m & blank && !iswblank_l(c, __l)) return false;
1049 return true;
1050#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001051}
1052
1053const wchar_t*
1054ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1055{
1056 for (; low != high; ++low, ++vec)
1057 {
1058 if (isascii(*low))
Alexis Hunt92b0c812011-07-09 00:56:23 +00001059 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001060 else
1061 {
1062 *vec = 0;
1063 if (iswspace_l(*low, __l))
1064 *vec |= space;
1065 if (iswprint_l(*low, __l))
1066 *vec |= print;
1067 if (iswcntrl_l(*low, __l))
1068 *vec |= cntrl;
1069 if (iswupper_l(*low, __l))
1070 *vec |= upper;
1071 if (iswlower_l(*low, __l))
1072 *vec |= lower;
1073 if (iswalpha_l(*low, __l))
1074 *vec |= alpha;
1075 if (iswdigit_l(*low, __l))
1076 *vec |= digit;
1077 if (iswpunct_l(*low, __l))
1078 *vec |= punct;
1079 if (iswxdigit_l(*low, __l))
1080 *vec |= xdigit;
1081 }
1082 }
1083 return low;
1084}
1085
1086const wchar_t*
1087ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1088{
1089 for (; low != high; ++low)
Alexis Huntc2017f12011-07-09 03:40:04 +00001090 {
1091#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantc51e1022010-05-11 19:42:16 +00001092 if (iswctype_l(*low, m, __l))
1093 break;
Alexis Huntc2017f12011-07-09 03:40:04 +00001094#else
1095 if (m & space && !iswspace_l(*low, __l)) continue;
1096 if (m & print && !iswprint_l(*low, __l)) continue;
1097 if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
1098 if (m & upper && !iswupper_l(*low, __l)) continue;
1099 if (m & lower && !iswlower_l(*low, __l)) continue;
1100 if (m & alpha && !iswalpha_l(*low, __l)) continue;
1101 if (m & digit && !iswdigit_l(*low, __l)) continue;
1102 if (m & punct && !iswpunct_l(*low, __l)) continue;
1103 if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
1104 if (m & blank && !iswblank_l(*low, __l)) continue;
1105 break;
1106#endif
1107 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001108 return low;
1109}
1110
1111const wchar_t*
1112ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1113{
1114 for (; low != high; ++low)
Alexis Huntc2017f12011-07-09 03:40:04 +00001115 {
1116#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantc51e1022010-05-11 19:42:16 +00001117 if (!iswctype_l(*low, m, __l))
1118 break;
Alexis Huntc2017f12011-07-09 03:40:04 +00001119#else
1120 if (m & space && iswspace_l(*low, __l)) continue;
1121 if (m & print && iswprint_l(*low, __l)) continue;
1122 if (m & cntrl && iswcntrl_l(*low, __l)) continue;
1123 if (m & upper && iswupper_l(*low, __l)) continue;
1124 if (m & lower && iswlower_l(*low, __l)) continue;
1125 if (m & alpha && iswalpha_l(*low, __l)) continue;
1126 if (m & digit && iswdigit_l(*low, __l)) continue;
1127 if (m & punct && iswpunct_l(*low, __l)) continue;
1128 if (m & xdigit && iswxdigit_l(*low, __l)) continue;
1129 if (m & blank && iswblank_l(*low, __l)) continue;
1130 break;
1131#endif
1132 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001133 return low;
1134}
1135
1136wchar_t
1137ctype_byname<wchar_t>::do_toupper(char_type c) const
1138{
1139 return towupper_l(c, __l);
1140}
1141
1142const wchar_t*
1143ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1144{
1145 for (; low != high; ++low)
1146 *low = towupper_l(*low, __l);
1147 return low;
1148}
1149
1150wchar_t
1151ctype_byname<wchar_t>::do_tolower(char_type c) const
1152{
1153 return towlower_l(c, __l);
1154}
1155
1156const wchar_t*
1157ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1158{
1159 for (; low != high; ++low)
1160 *low = towlower_l(*low, __l);
1161 return low;
1162}
1163
1164wchar_t
1165ctype_byname<wchar_t>::do_widen(char c) const
1166{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001167#ifdef _LIBCPP_STABLE_APPLE_ABI
1168 return btowc_l(c, __l);
1169#else
1170 return __btowc_l(c, __l);
1171#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001172}
1173
1174const char*
1175ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1176{
1177 for (; low != high; ++low, ++dest)
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001178#ifdef _LIBCPP_STABLE_APPLE_ABI
1179 *dest = btowc_l(*low, __l);
1180#else
1181 *dest = __btowc_l(*low, __l);
1182#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001183 return low;
1184}
1185
1186char
1187ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1188{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001189#ifdef _LIBCPP_STABLE_APPLE_ABI
1190 int r = wctob_l(c, __l);
1191#else
1192 int r = __wctob_l(c, __l);
1193#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001194 return r != WEOF ? static_cast<char>(r) : dfault;
1195}
1196
1197const wchar_t*
1198ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1199{
1200 for (; low != high; ++low, ++dest)
1201 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001202#ifdef _LIBCPP_STABLE_APPLE_ABI
1203 int r = wctob_l(*low, __l);
1204#else
1205 int r = __wctob_l(*low, __l);
1206#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001207 *dest = r != WEOF ? static_cast<char>(r) : dfault;
1208 }
1209 return low;
1210}
1211
1212// template <> class codecvt<char, char, mbstate_t>
1213
Howard Hinnantffb308e2010-08-22 00:03:27 +00001214locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001215
1216codecvt<char, char, mbstate_t>::~codecvt()
1217{
1218}
1219
1220codecvt<char, char, mbstate_t>::result
Howard Hinnantffb308e2010-08-22 00:03:27 +00001221codecvt<char, char, mbstate_t>::do_out(state_type&,
1222 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001223 extern_type* to, extern_type*, extern_type*& to_nxt) const
1224{
1225 frm_nxt = frm;
1226 to_nxt = to;
1227 return noconv;
1228}
1229
1230codecvt<char, char, mbstate_t>::result
Howard Hinnantffb308e2010-08-22 00:03:27 +00001231codecvt<char, char, mbstate_t>::do_in(state_type&,
1232 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001233 intern_type* to, intern_type*, intern_type*& to_nxt) const
1234{
1235 frm_nxt = frm;
1236 to_nxt = to;
1237 return noconv;
1238}
1239
1240codecvt<char, char, mbstate_t>::result
Howard Hinnantffb308e2010-08-22 00:03:27 +00001241codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001242 extern_type* to, extern_type*, extern_type*& to_nxt) const
1243{
1244 to_nxt = to;
1245 return noconv;
1246}
1247
1248int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001249codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001250{
1251 return 1;
1252}
1253
1254bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001255codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001256{
1257 return true;
1258}
1259
1260int
1261codecvt<char, char, mbstate_t>::do_length(state_type&,
1262 const extern_type* frm, const extern_type* end, size_t mx) const
1263{
1264 return static_cast<int>(min<size_t>(mx, end-frm));
1265}
1266
1267int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001268codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001269{
1270 return 1;
1271}
1272
1273// template <> class codecvt<wchar_t, char, mbstate_t>
1274
Howard Hinnantffb308e2010-08-22 00:03:27 +00001275locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276
1277codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1278 : locale::facet(refs),
1279 __l(0)
1280{
1281}
1282
1283codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1284 : locale::facet(refs),
1285 __l(newlocale(LC_ALL_MASK, nm, 0))
1286{
Howard Hinnant72f73582010-08-11 17:04:31 +00001287#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001288 if (__l == 0)
1289 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1290 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00001291#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00001292}
1293
1294codecvt<wchar_t, char, mbstate_t>::~codecvt()
1295{
1296 if (__l != 0)
1297 freelocale(__l);
1298}
1299
1300codecvt<wchar_t, char, mbstate_t>::result
1301codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnantffb308e2010-08-22 00:03:27 +00001302 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001303 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1304{
1305 // look for first internal null in frm
1306 const intern_type* fend = frm;
1307 for (; fend != frm_end; ++fend)
1308 if (*fend == 0)
1309 break;
1310 // loop over all null-terminated sequences in frm
1311 to_nxt = to;
1312 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1313 {
1314 // save state in case needed to reover to_nxt on error
1315 mbstate_t save_state = st;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001316#ifdef _LIBCPP_STABLE_APPLE_ABI
1317 size_t n = wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1318#else
1319 size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1320#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001321 if (n == size_t(-1))
1322 {
1323 // need to recover to_nxt
1324 for (to_nxt = to; frm != frm_nxt; ++frm)
1325 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001326#ifdef _LIBCPP_STABLE_APPLE_ABI
1327 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1328#else
1329 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1330#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001331 if (n == size_t(-1))
1332 break;
1333 to_nxt += n;
1334 }
1335 frm_nxt = frm;
1336 return error;
1337 }
1338 if (n == 0)
1339 return partial;
1340 to_nxt += n;
1341 if (to_nxt == to_end)
1342 break;
1343 if (fend != frm_end) // set up next null terminated sequence
1344 {
1345 // Try to write the terminating null
1346 extern_type tmp[MB_LEN_MAX];
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001347#ifdef _LIBCPP_STABLE_APPLE_ABI
1348 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1349#else
1350 n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1351#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001352 if (n == size_t(-1)) // on error
1353 return error;
1354 if (n > to_end-to_nxt) // is there room?
1355 return partial;
1356 for (extern_type* p = tmp; n; --n) // write it
1357 *to_nxt++ = *p++;
1358 ++frm_nxt;
1359 // look for next null in frm
1360 for (fend = frm_nxt; fend != frm_end; ++fend)
1361 if (*fend == 0)
1362 break;
1363 }
1364 }
1365 return frm_nxt == frm_end ? ok : partial;
1366}
1367
1368codecvt<wchar_t, char, mbstate_t>::result
1369codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnantffb308e2010-08-22 00:03:27 +00001370 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001371 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1372{
1373 // look for first internal null in frm
1374 const extern_type* fend = frm;
1375 for (; fend != frm_end; ++fend)
1376 if (*fend == 0)
1377 break;
1378 // loop over all null-terminated sequences in frm
1379 to_nxt = to;
1380 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1381 {
1382 // save state in case needed to reover to_nxt on error
1383 mbstate_t save_state = st;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001384#ifdef _LIBCPP_STABLE_APPLE_ABI
1385 size_t n = mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1386#else
1387 size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1388#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001389 if (n == size_t(-1))
1390 {
1391 // need to recover to_nxt
1392 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1393 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001394#ifdef _LIBCPP_STABLE_APPLE_ABI
1395 n = mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1396#else
1397 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1398#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001399 switch (n)
1400 {
1401 case 0:
1402 ++frm;
1403 break;
1404 case -1:
1405 frm_nxt = frm;
1406 return error;
1407 case -2:
1408 frm_nxt = frm;
1409 return partial;
1410 default:
1411 frm += n;
1412 break;
1413 }
1414 }
1415 frm_nxt = frm;
1416 return frm_nxt == frm_end ? ok : partial;
1417 }
1418 if (n == 0)
1419 return error;
1420 to_nxt += n;
1421 if (to_nxt == to_end)
1422 break;
1423 if (fend != frm_end) // set up next null terminated sequence
1424 {
1425 // Try to write the terminating null
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001426#ifdef _LIBCPP_STABLE_APPLE_ABI
1427 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1428#else
1429 n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1430#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001431 if (n != 0) // on error
1432 return error;
1433 ++to_nxt;
1434 ++frm_nxt;
1435 // look for next null in frm
1436 for (fend = frm_nxt; fend != frm_end; ++fend)
1437 if (*fend == 0)
1438 break;
1439 }
1440 }
1441 return frm_nxt == frm_end ? ok : partial;
1442}
1443
1444codecvt<wchar_t, char, mbstate_t>::result
1445codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1446 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1447{
1448 to_nxt = to;
1449 extern_type tmp[MB_LEN_MAX];
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001450#ifdef _LIBCPP_STABLE_APPLE_ABI
1451 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1452#else
1453 size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1454#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001455 if (n == size_t(-1) || n == 0) // on error
1456 return error;
1457 --n;
1458 if (n > to_end-to_nxt) // is there room?
1459 return partial;
1460 for (extern_type* p = tmp; n; --n) // write it
1461 *to_nxt++ = *p++;
1462 return ok;
1463}
1464
1465int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001466codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001467{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001468#ifdef _LIBCPP_STABLE_APPLE_ABI
1469 if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1470#else
1471 if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1472#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001473 {
1474 // stateless encoding
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001475#ifdef _LIBCPP_STABLE_APPLE_ABI
1476 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1477#else
1478 if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1479#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001480 return 1; // which take more than 1 char to form a wchar_t
1481 return 0;
1482 }
1483 return -1;
1484}
1485
1486bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001487codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001488{
1489 return false;
1490}
1491
1492int
1493codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1494 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1495{
1496 int nbytes = 0;
1497 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1498 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001499#ifdef _LIBCPP_STABLE_APPLE_ABI
1500 size_t n = mbrlen_l(frm, frm_end-frm, &st, __l);
1501#else
1502 size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1503#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001504 switch (n)
1505 {
1506 case 0:
1507 ++nbytes;
1508 ++frm;
1509 break;
1510 case -1:
1511 case -2:
1512 return nbytes;
1513 default:
1514 nbytes += n;
1515 frm += n;
1516 break;
1517 }
1518 }
1519 return nbytes;
1520}
1521
1522int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001523codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001524{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001525#ifdef _LIBCPP_STABLE_APPLE_ABI
1526 return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
1527#else
1528 return __l == 0 ? 1 : __mb_cur_max_l(__l);
1529#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001530}
1531
1532// Valid UTF ranges
1533// UTF-32 UTF-16 UTF-8 # of code points
1534// first second first second third fourth
1535// 000000 - 00007F 0000 - 007F 00 - 7F 127
1536// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1537// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1538// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1539// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1540// 00D800 - 00DFFF invalid
1541// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1542// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1543// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1544// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1545
Howard Hinnant7282c5a2010-05-30 21:39:41 +00001546static
1547codecvt_base::result
1548utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1549 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1550 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1551{
1552 frm_nxt = frm;
1553 to_nxt = to;
1554 if (mode & generate_header)
1555 {
1556 if (to_end-to_nxt < 3)
1557 return codecvt_base::partial;
1558 *to_nxt++ = static_cast<uint8_t>(0xEF);
1559 *to_nxt++ = static_cast<uint8_t>(0xBB);
1560 *to_nxt++ = static_cast<uint8_t>(0xBF);
1561 }
1562 for (; frm_nxt < frm_end; ++frm_nxt)
1563 {
1564 uint16_t wc1 = *frm_nxt;
1565 if (wc1 > Maxcode)
1566 return codecvt_base::error;
1567 if (wc1 < 0x0080)
1568 {
1569 if (to_end-to_nxt < 1)
1570 return codecvt_base::partial;
1571 *to_nxt++ = static_cast<uint8_t>(wc1);
1572 }
1573 else if (wc1 < 0x0800)
1574 {
1575 if (to_end-to_nxt < 2)
1576 return codecvt_base::partial;
1577 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1578 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1579 }
1580 else if (wc1 < 0xD800)
1581 {
1582 if (to_end-to_nxt < 3)
1583 return codecvt_base::partial;
1584 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1585 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1586 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1587 }
1588 else if (wc1 < 0xDC00)
1589 {
1590 if (frm_end-frm_nxt < 2)
1591 return codecvt_base::partial;
1592 uint16_t wc2 = frm_nxt[1];
1593 if ((wc2 & 0xFC00) != 0xDC00)
1594 return codecvt_base::error;
1595 if (to_end-to_nxt < 4)
1596 return codecvt_base::partial;
1597 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1598 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1599 return codecvt_base::error;
1600 ++frm_nxt;
1601 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1602 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1603 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1604 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1605 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1606 }
1607 else if (wc1 < 0xE000)
1608 {
1609 return codecvt_base::error;
1610 }
1611 else
1612 {
1613 if (to_end-to_nxt < 3)
1614 return codecvt_base::partial;
1615 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1616 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1617 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1618 }
1619 }
1620 return codecvt_base::ok;
1621}
1622
1623static
1624codecvt_base::result
1625utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1626 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1627 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1628{
1629 frm_nxt = frm;
1630 to_nxt = to;
1631 if (mode & generate_header)
1632 {
1633 if (to_end-to_nxt < 3)
1634 return codecvt_base::partial;
1635 *to_nxt++ = static_cast<uint8_t>(0xEF);
1636 *to_nxt++ = static_cast<uint8_t>(0xBB);
1637 *to_nxt++ = static_cast<uint8_t>(0xBF);
1638 }
1639 for (; frm_nxt < frm_end; ++frm_nxt)
1640 {
1641 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1642 if (wc1 > Maxcode)
1643 return codecvt_base::error;
1644 if (wc1 < 0x0080)
1645 {
1646 if (to_end-to_nxt < 1)
1647 return codecvt_base::partial;
1648 *to_nxt++ = static_cast<uint8_t>(wc1);
1649 }
1650 else if (wc1 < 0x0800)
1651 {
1652 if (to_end-to_nxt < 2)
1653 return codecvt_base::partial;
1654 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1655 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1656 }
1657 else if (wc1 < 0xD800)
1658 {
1659 if (to_end-to_nxt < 3)
1660 return codecvt_base::partial;
1661 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1662 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1663 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1664 }
1665 else if (wc1 < 0xDC00)
1666 {
1667 if (frm_end-frm_nxt < 2)
1668 return codecvt_base::partial;
1669 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1670 if ((wc2 & 0xFC00) != 0xDC00)
1671 return codecvt_base::error;
1672 if (to_end-to_nxt < 4)
1673 return codecvt_base::partial;
1674 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1675 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1676 return codecvt_base::error;
1677 ++frm_nxt;
1678 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1679 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1680 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1681 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1682 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1683 }
1684 else if (wc1 < 0xE000)
1685 {
1686 return codecvt_base::error;
1687 }
1688 else
1689 {
1690 if (to_end-to_nxt < 3)
1691 return codecvt_base::partial;
1692 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1693 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1694 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1695 }
1696 }
1697 return codecvt_base::ok;
1698}
1699
1700static
1701codecvt_base::result
1702utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1703 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1704 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1705{
1706 frm_nxt = frm;
1707 to_nxt = to;
1708 if (mode & consume_header)
1709 {
1710 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1711 frm_nxt[2] == 0xBF)
1712 frm_nxt += 3;
1713 }
1714 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1715 {
1716 uint8_t c1 = *frm_nxt;
1717 if (c1 > Maxcode)
1718 return codecvt_base::error;
1719 if (c1 < 0x80)
1720 {
1721 *to_nxt = static_cast<uint16_t>(c1);
1722 ++frm_nxt;
1723 }
1724 else if (c1 < 0xC2)
1725 {
1726 return codecvt_base::error;
1727 }
1728 else if (c1 < 0xE0)
1729 {
1730 if (frm_end-frm_nxt < 2)
1731 return codecvt_base::partial;
1732 uint8_t c2 = frm_nxt[1];
1733 if ((c2 & 0xC0) != 0x80)
1734 return codecvt_base::error;
1735 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1736 if (t > Maxcode)
1737 return codecvt_base::error;
1738 *to_nxt = t;
1739 frm_nxt += 2;
1740 }
1741 else if (c1 < 0xF0)
1742 {
1743 if (frm_end-frm_nxt < 3)
1744 return codecvt_base::partial;
1745 uint8_t c2 = frm_nxt[1];
1746 uint8_t c3 = frm_nxt[2];
1747 switch (c1)
1748 {
1749 case 0xE0:
1750 if ((c2 & 0xE0) != 0xA0)
1751 return codecvt_base::error;
1752 break;
1753 case 0xED:
1754 if ((c2 & 0xE0) != 0x80)
1755 return codecvt_base::error;
1756 break;
1757 default:
1758 if ((c2 & 0xC0) != 0x80)
1759 return codecvt_base::error;
1760 break;
1761 }
1762 if ((c3 & 0xC0) != 0x80)
1763 return codecvt_base::error;
1764 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1765 | ((c2 & 0x3F) << 6)
1766 | (c3 & 0x3F));
1767 if (t > Maxcode)
1768 return codecvt_base::error;
1769 *to_nxt = t;
1770 frm_nxt += 3;
1771 }
1772 else if (c1 < 0xF5)
1773 {
1774 if (frm_end-frm_nxt < 4)
1775 return codecvt_base::partial;
1776 uint8_t c2 = frm_nxt[1];
1777 uint8_t c3 = frm_nxt[2];
1778 uint8_t c4 = frm_nxt[3];
1779 switch (c1)
1780 {
1781 case 0xF0:
1782 if (!(0x90 <= c2 && c2 <= 0xBF))
1783 return codecvt_base::error;
1784 break;
1785 case 0xF4:
1786 if ((c2 & 0xF0) != 0x80)
1787 return codecvt_base::error;
1788 break;
1789 default:
1790 if ((c2 & 0xC0) != 0x80)
1791 return codecvt_base::error;
1792 break;
1793 }
1794 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1795 return codecvt_base::error;
1796 if (to_end-to_nxt < 2)
1797 return codecvt_base::partial;
1798 if (((((unsigned long)c1 & 7) << 18) +
1799 (((unsigned long)c2 & 0x3F) << 12) +
1800 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1801 return codecvt_base::error;
1802 *to_nxt = static_cast<uint16_t>(
1803 0xD800
1804 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1805 | ((c2 & 0x0F) << 2)
1806 | ((c3 & 0x30) >> 4));
1807 *++to_nxt = static_cast<uint16_t>(
1808 0xDC00
1809 | ((c3 & 0x0F) << 6)
1810 | (c4 & 0x3F));
1811 frm_nxt += 4;
1812 }
1813 else
1814 {
1815 return codecvt_base::error;
1816 }
1817 }
1818 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1819}
1820
1821static
1822codecvt_base::result
1823utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1824 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1825 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1826{
1827 frm_nxt = frm;
1828 to_nxt = to;
1829 if (mode & consume_header)
1830 {
1831 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1832 frm_nxt[2] == 0xBF)
1833 frm_nxt += 3;
1834 }
1835 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1836 {
1837 uint8_t c1 = *frm_nxt;
1838 if (c1 > Maxcode)
1839 return codecvt_base::error;
1840 if (c1 < 0x80)
1841 {
1842 *to_nxt = static_cast<uint32_t>(c1);
1843 ++frm_nxt;
1844 }
1845 else if (c1 < 0xC2)
1846 {
1847 return codecvt_base::error;
1848 }
1849 else if (c1 < 0xE0)
1850 {
1851 if (frm_end-frm_nxt < 2)
1852 return codecvt_base::partial;
1853 uint8_t c2 = frm_nxt[1];
1854 if ((c2 & 0xC0) != 0x80)
1855 return codecvt_base::error;
1856 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1857 if (t > Maxcode)
1858 return codecvt_base::error;
1859 *to_nxt = static_cast<uint32_t>(t);
1860 frm_nxt += 2;
1861 }
1862 else if (c1 < 0xF0)
1863 {
1864 if (frm_end-frm_nxt < 3)
1865 return codecvt_base::partial;
1866 uint8_t c2 = frm_nxt[1];
1867 uint8_t c3 = frm_nxt[2];
1868 switch (c1)
1869 {
1870 case 0xE0:
1871 if ((c2 & 0xE0) != 0xA0)
1872 return codecvt_base::error;
1873 break;
1874 case 0xED:
1875 if ((c2 & 0xE0) != 0x80)
1876 return codecvt_base::error;
1877 break;
1878 default:
1879 if ((c2 & 0xC0) != 0x80)
1880 return codecvt_base::error;
1881 break;
1882 }
1883 if ((c3 & 0xC0) != 0x80)
1884 return codecvt_base::error;
1885 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1886 | ((c2 & 0x3F) << 6)
1887 | (c3 & 0x3F));
1888 if (t > Maxcode)
1889 return codecvt_base::error;
1890 *to_nxt = static_cast<uint32_t>(t);
1891 frm_nxt += 3;
1892 }
1893 else if (c1 < 0xF5)
1894 {
1895 if (frm_end-frm_nxt < 4)
1896 return codecvt_base::partial;
1897 uint8_t c2 = frm_nxt[1];
1898 uint8_t c3 = frm_nxt[2];
1899 uint8_t c4 = frm_nxt[3];
1900 switch (c1)
1901 {
1902 case 0xF0:
1903 if (!(0x90 <= c2 && c2 <= 0xBF))
1904 return codecvt_base::error;
1905 break;
1906 case 0xF4:
1907 if ((c2 & 0xF0) != 0x80)
1908 return codecvt_base::error;
1909 break;
1910 default:
1911 if ((c2 & 0xC0) != 0x80)
1912 return codecvt_base::error;
1913 break;
1914 }
1915 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1916 return codecvt_base::error;
1917 if (to_end-to_nxt < 2)
1918 return codecvt_base::partial;
1919 if (((((unsigned long)c1 & 7) << 18) +
1920 (((unsigned long)c2 & 0x3F) << 12) +
1921 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1922 return codecvt_base::error;
1923 *to_nxt = static_cast<uint32_t>(
1924 0xD800
1925 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1926 | ((c2 & 0x0F) << 2)
1927 | ((c3 & 0x30) >> 4));
1928 *++to_nxt = static_cast<uint32_t>(
1929 0xDC00
1930 | ((c3 & 0x0F) << 6)
1931 | (c4 & 0x3F));
1932 frm_nxt += 4;
1933 }
1934 else
1935 {
1936 return codecvt_base::error;
1937 }
1938 }
1939 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1940}
1941
1942static
1943int
1944utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1945 size_t mx, unsigned long Maxcode = 0x10FFFF,
1946 codecvt_mode mode = codecvt_mode(0))
1947{
1948 const uint8_t* frm_nxt = frm;
1949 if (mode & consume_header)
1950 {
1951 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1952 frm_nxt[2] == 0xBF)
1953 frm_nxt += 3;
1954 }
1955 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1956 {
1957 uint8_t c1 = *frm_nxt;
1958 if (c1 > Maxcode)
1959 break;
1960 if (c1 < 0x80)
1961 {
1962 ++frm_nxt;
1963 }
1964 else if (c1 < 0xC2)
1965 {
1966 break;
1967 }
1968 else if (c1 < 0xE0)
1969 {
1970 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1971 break;
1972 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1973 if (t > Maxcode)
1974 break;
1975 frm_nxt += 2;
1976 }
1977 else if (c1 < 0xF0)
1978 {
1979 if (frm_end-frm_nxt < 3)
1980 break;
1981 uint8_t c2 = frm_nxt[1];
1982 uint8_t c3 = frm_nxt[2];
1983 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1984 | ((c2 & 0x3F) << 6)
1985 | (c3 & 0x3F));
1986 switch (c1)
1987 {
1988 case 0xE0:
1989 if ((c2 & 0xE0) != 0xA0)
1990 return static_cast<int>(frm_nxt - frm);
1991 break;
1992 case 0xED:
1993 if ((c2 & 0xE0) != 0x80)
1994 return static_cast<int>(frm_nxt - frm);
1995 break;
1996 default:
1997 if ((c2 & 0xC0) != 0x80)
1998 return static_cast<int>(frm_nxt - frm);
1999 break;
2000 }
2001 if ((c3 & 0xC0) != 0x80)
2002 break;
2003 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2004 break;
2005 frm_nxt += 3;
2006 }
2007 else if (c1 < 0xF5)
2008 {
2009 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2010 break;
2011 uint8_t c2 = frm_nxt[1];
2012 uint8_t c3 = frm_nxt[2];
2013 uint8_t c4 = frm_nxt[3];
2014 switch (c1)
2015 {
2016 case 0xF0:
2017 if (!(0x90 <= c2 && c2 <= 0xBF))
2018 return static_cast<int>(frm_nxt - frm);
2019 break;
2020 case 0xF4:
2021 if ((c2 & 0xF0) != 0x80)
2022 return static_cast<int>(frm_nxt - frm);
2023 break;
2024 default:
2025 if ((c2 & 0xC0) != 0x80)
2026 return static_cast<int>(frm_nxt - frm);
2027 break;
2028 }
2029 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2030 break;
2031 if (((((unsigned long)c1 & 7) << 18) +
2032 (((unsigned long)c2 & 0x3F) << 12) +
2033 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
2034 break;
2035 ++nchar16_t;
2036 frm_nxt += 4;
2037 }
2038 else
2039 {
2040 break;
2041 }
2042 }
2043 return static_cast<int>(frm_nxt - frm);
2044}
2045
2046static
2047codecvt_base::result
2048ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2049 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2050 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2051{
2052 frm_nxt = frm;
2053 to_nxt = to;
2054 if (mode & generate_header)
2055 {
2056 if (to_end-to_nxt < 3)
2057 return codecvt_base::partial;
2058 *to_nxt++ = static_cast<uint8_t>(0xEF);
2059 *to_nxt++ = static_cast<uint8_t>(0xBB);
2060 *to_nxt++ = static_cast<uint8_t>(0xBF);
2061 }
2062 for (; frm_nxt < frm_end; ++frm_nxt)
2063 {
2064 uint32_t wc = *frm_nxt;
2065 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2066 return codecvt_base::error;
2067 if (wc < 0x000080)
2068 {
2069 if (to_end-to_nxt < 1)
2070 return codecvt_base::partial;
2071 *to_nxt++ = static_cast<uint8_t>(wc);
2072 }
2073 else if (wc < 0x000800)
2074 {
2075 if (to_end-to_nxt < 2)
2076 return codecvt_base::partial;
2077 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2078 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2079 }
2080 else if (wc < 0x010000)
2081 {
2082 if (to_end-to_nxt < 3)
2083 return codecvt_base::partial;
2084 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2085 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2086 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2087 }
2088 else // if (wc < 0x110000)
2089 {
2090 if (to_end-to_nxt < 4)
2091 return codecvt_base::partial;
2092 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2093 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2094 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2095 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2096 }
2097 }
2098 return codecvt_base::ok;
2099}
2100
2101static
2102codecvt_base::result
2103utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2104 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2105 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2106{
2107 frm_nxt = frm;
2108 to_nxt = to;
2109 if (mode & consume_header)
2110 {
2111 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2112 frm_nxt[2] == 0xBF)
2113 frm_nxt += 3;
2114 }
2115 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2116 {
2117 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2118 if (c1 < 0x80)
2119 {
2120 if (c1 > Maxcode)
2121 return codecvt_base::error;
2122 *to_nxt = static_cast<uint32_t>(c1);
2123 ++frm_nxt;
2124 }
2125 else if (c1 < 0xC2)
2126 {
2127 return codecvt_base::error;
2128 }
2129 else if (c1 < 0xE0)
2130 {
2131 if (frm_end-frm_nxt < 2)
2132 return codecvt_base::partial;
2133 uint8_t c2 = frm_nxt[1];
2134 if ((c2 & 0xC0) != 0x80)
2135 return codecvt_base::error;
2136 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2137 | (c2 & 0x3F));
2138 if (t > Maxcode)
2139 return codecvt_base::error;
2140 *to_nxt = t;
2141 frm_nxt += 2;
2142 }
2143 else if (c1 < 0xF0)
2144 {
2145 if (frm_end-frm_nxt < 3)
2146 return codecvt_base::partial;
2147 uint8_t c2 = frm_nxt[1];
2148 uint8_t c3 = frm_nxt[2];
2149 switch (c1)
2150 {
2151 case 0xE0:
2152 if ((c2 & 0xE0) != 0xA0)
2153 return codecvt_base::error;
2154 break;
2155 case 0xED:
2156 if ((c2 & 0xE0) != 0x80)
2157 return codecvt_base::error;
2158 break;
2159 default:
2160 if ((c2 & 0xC0) != 0x80)
2161 return codecvt_base::error;
2162 break;
2163 }
2164 if ((c3 & 0xC0) != 0x80)
2165 return codecvt_base::error;
2166 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2167 | ((c2 & 0x3F) << 6)
2168 | (c3 & 0x3F));
2169 if (t > Maxcode)
2170 return codecvt_base::error;
2171 *to_nxt = t;
2172 frm_nxt += 3;
2173 }
2174 else if (c1 < 0xF5)
2175 {
2176 if (frm_end-frm_nxt < 4)
2177 return codecvt_base::partial;
2178 uint8_t c2 = frm_nxt[1];
2179 uint8_t c3 = frm_nxt[2];
2180 uint8_t c4 = frm_nxt[3];
2181 switch (c1)
2182 {
2183 case 0xF0:
2184 if (!(0x90 <= c2 && c2 <= 0xBF))
2185 return codecvt_base::error;
2186 break;
2187 case 0xF4:
2188 if ((c2 & 0xF0) != 0x80)
2189 return codecvt_base::error;
2190 break;
2191 default:
2192 if ((c2 & 0xC0) != 0x80)
2193 return codecvt_base::error;
2194 break;
2195 }
2196 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2197 return codecvt_base::error;
2198 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2199 | ((c2 & 0x3F) << 12)
2200 | ((c3 & 0x3F) << 6)
2201 | (c4 & 0x3F));
2202 if (t > Maxcode)
2203 return codecvt_base::error;
2204 *to_nxt = t;
2205 frm_nxt += 4;
2206 }
2207 else
2208 {
2209 return codecvt_base::error;
2210 }
2211 }
2212 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2213}
2214
2215static
2216int
2217utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2218 size_t mx, unsigned long Maxcode = 0x10FFFF,
2219 codecvt_mode mode = codecvt_mode(0))
2220{
2221 const uint8_t* frm_nxt = frm;
2222 if (mode & consume_header)
2223 {
2224 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2225 frm_nxt[2] == 0xBF)
2226 frm_nxt += 3;
2227 }
2228 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2229 {
2230 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2231 if (c1 < 0x80)
2232 {
2233 if (c1 > Maxcode)
2234 break;
2235 ++frm_nxt;
2236 }
2237 else if (c1 < 0xC2)
2238 {
2239 break;
2240 }
2241 else if (c1 < 0xE0)
2242 {
2243 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2244 break;
2245 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2246 break;
2247 frm_nxt += 2;
2248 }
2249 else if (c1 < 0xF0)
2250 {
2251 if (frm_end-frm_nxt < 3)
2252 break;
2253 uint8_t c2 = frm_nxt[1];
2254 uint8_t c3 = frm_nxt[2];
2255 switch (c1)
2256 {
2257 case 0xE0:
2258 if ((c2 & 0xE0) != 0xA0)
2259 return static_cast<int>(frm_nxt - frm);
2260 break;
2261 case 0xED:
2262 if ((c2 & 0xE0) != 0x80)
2263 return static_cast<int>(frm_nxt - frm);
2264 break;
2265 default:
2266 if ((c2 & 0xC0) != 0x80)
2267 return static_cast<int>(frm_nxt - frm);
2268 break;
2269 }
2270 if ((c3 & 0xC0) != 0x80)
2271 break;
2272 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2273 break;
2274 frm_nxt += 3;
2275 }
2276 else if (c1 < 0xF5)
2277 {
2278 if (frm_end-frm_nxt < 4)
2279 break;
2280 uint8_t c2 = frm_nxt[1];
2281 uint8_t c3 = frm_nxt[2];
2282 uint8_t c4 = frm_nxt[3];
2283 switch (c1)
2284 {
2285 case 0xF0:
2286 if (!(0x90 <= c2 && c2 <= 0xBF))
2287 return static_cast<int>(frm_nxt - frm);
2288 break;
2289 case 0xF4:
2290 if ((c2 & 0xF0) != 0x80)
2291 return static_cast<int>(frm_nxt - frm);
2292 break;
2293 default:
2294 if ((c2 & 0xC0) != 0x80)
2295 return static_cast<int>(frm_nxt - frm);
2296 break;
2297 }
2298 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2299 break;
2300 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2301 | ((c2 & 0x3F) << 12)
2302 | ((c3 & 0x3F) << 6)
2303 | (c4 & 0x3F));
2304 if ((((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
2305 ((c3 & 0x3F) << 6) | (c4 & 0x3F)) > Maxcode)
2306 break;
2307 frm_nxt += 4;
2308 }
2309 else
2310 {
2311 break;
2312 }
2313 }
2314 return static_cast<int>(frm_nxt - frm);
2315}
2316
2317static
2318codecvt_base::result
2319ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2320 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2321 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2322{
2323 frm_nxt = frm;
2324 to_nxt = to;
2325 if (mode & generate_header)
2326 {
2327 if (to_end-to_nxt < 3)
2328 return codecvt_base::partial;
2329 *to_nxt++ = static_cast<uint8_t>(0xEF);
2330 *to_nxt++ = static_cast<uint8_t>(0xBB);
2331 *to_nxt++ = static_cast<uint8_t>(0xBF);
2332 }
2333 for (; frm_nxt < frm_end; ++frm_nxt)
2334 {
2335 uint16_t wc = *frm_nxt;
2336 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2337 return codecvt_base::error;
2338 if (wc < 0x0080)
2339 {
2340 if (to_end-to_nxt < 1)
2341 return codecvt_base::partial;
2342 *to_nxt++ = static_cast<uint8_t>(wc);
2343 }
2344 else if (wc < 0x0800)
2345 {
2346 if (to_end-to_nxt < 2)
2347 return codecvt_base::partial;
2348 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2349 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2350 }
2351 else // if (wc <= 0xFFFF)
2352 {
2353 if (to_end-to_nxt < 3)
2354 return codecvt_base::partial;
2355 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2356 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2357 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2358 }
2359 }
2360 return codecvt_base::ok;
2361}
2362
2363static
2364codecvt_base::result
2365utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2366 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2367 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2368{
2369 frm_nxt = frm;
2370 to_nxt = to;
2371 if (mode & consume_header)
2372 {
2373 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2374 frm_nxt[2] == 0xBF)
2375 frm_nxt += 3;
2376 }
2377 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2378 {
2379 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2380 if (c1 < 0x80)
2381 {
2382 if (c1 > Maxcode)
2383 return codecvt_base::error;
2384 *to_nxt = static_cast<uint16_t>(c1);
2385 ++frm_nxt;
2386 }
2387 else if (c1 < 0xC2)
2388 {
2389 return codecvt_base::error;
2390 }
2391 else if (c1 < 0xE0)
2392 {
2393 if (frm_end-frm_nxt < 2)
2394 return codecvt_base::partial;
2395 uint8_t c2 = frm_nxt[1];
2396 if ((c2 & 0xC0) != 0x80)
2397 return codecvt_base::error;
2398 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2399 | (c2 & 0x3F));
2400 if (t > Maxcode)
2401 return codecvt_base::error;
2402 *to_nxt = t;
2403 frm_nxt += 2;
2404 }
2405 else if (c1 < 0xF0)
2406 {
2407 if (frm_end-frm_nxt < 3)
2408 return codecvt_base::partial;
2409 uint8_t c2 = frm_nxt[1];
2410 uint8_t c3 = frm_nxt[2];
2411 switch (c1)
2412 {
2413 case 0xE0:
2414 if ((c2 & 0xE0) != 0xA0)
2415 return codecvt_base::error;
2416 break;
2417 case 0xED:
2418 if ((c2 & 0xE0) != 0x80)
2419 return codecvt_base::error;
2420 break;
2421 default:
2422 if ((c2 & 0xC0) != 0x80)
2423 return codecvt_base::error;
2424 break;
2425 }
2426 if ((c3 & 0xC0) != 0x80)
2427 return codecvt_base::error;
2428 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2429 | ((c2 & 0x3F) << 6)
2430 | (c3 & 0x3F));
2431 if (t > Maxcode)
2432 return codecvt_base::error;
2433 *to_nxt = t;
2434 frm_nxt += 3;
2435 }
2436 else
2437 {
2438 return codecvt_base::error;
2439 }
2440 }
2441 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2442}
2443
2444static
2445int
2446utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2447 size_t mx, unsigned long Maxcode = 0x10FFFF,
2448 codecvt_mode mode = codecvt_mode(0))
2449{
2450 const uint8_t* frm_nxt = frm;
2451 if (mode & consume_header)
2452 {
2453 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2454 frm_nxt[2] == 0xBF)
2455 frm_nxt += 3;
2456 }
2457 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2458 {
2459 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2460 if (c1 < 0x80)
2461 {
2462 if (c1 > Maxcode)
2463 break;
2464 ++frm_nxt;
2465 }
2466 else if (c1 < 0xC2)
2467 {
2468 break;
2469 }
2470 else if (c1 < 0xE0)
2471 {
2472 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2473 break;
2474 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2475 break;
2476 frm_nxt += 2;
2477 }
2478 else if (c1 < 0xF0)
2479 {
2480 if (frm_end-frm_nxt < 3)
2481 break;
2482 uint8_t c2 = frm_nxt[1];
2483 uint8_t c3 = frm_nxt[2];
2484 switch (c1)
2485 {
2486 case 0xE0:
2487 if ((c2 & 0xE0) != 0xA0)
2488 return static_cast<int>(frm_nxt - frm);
2489 break;
2490 case 0xED:
2491 if ((c2 & 0xE0) != 0x80)
2492 return static_cast<int>(frm_nxt - frm);
2493 break;
2494 default:
2495 if ((c2 & 0xC0) != 0x80)
2496 return static_cast<int>(frm_nxt - frm);
2497 break;
2498 }
2499 if ((c3 & 0xC0) != 0x80)
2500 break;
2501 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2502 break;
2503 frm_nxt += 3;
2504 }
2505 else
2506 {
2507 break;
2508 }
2509 }
2510 return static_cast<int>(frm_nxt - frm);
2511}
2512
2513static
2514codecvt_base::result
2515ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2516 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2517 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2518{
2519 frm_nxt = frm;
2520 to_nxt = to;
2521 if (mode & generate_header)
2522 {
2523 if (to_end-to_nxt < 2)
2524 return codecvt_base::partial;
2525 *to_nxt++ = static_cast<uint8_t>(0xFE);
2526 *to_nxt++ = static_cast<uint8_t>(0xFF);
2527 }
2528 for (; frm_nxt < frm_end; ++frm_nxt)
2529 {
2530 uint32_t wc = *frm_nxt;
2531 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2532 return codecvt_base::error;
2533 if (wc < 0x010000)
2534 {
2535 if (to_end-to_nxt < 2)
2536 return codecvt_base::partial;
2537 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2538 *to_nxt++ = static_cast<uint8_t>(wc);
2539 }
2540 else
2541 {
2542 if (to_end-to_nxt < 4)
2543 return codecvt_base::partial;
2544 uint16_t t = static_cast<uint16_t>(
2545 0xD800
2546 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2547 | ((wc & 0x00FC00) >> 10));
2548 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2549 *to_nxt++ = static_cast<uint8_t>(t);
2550 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2551 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2552 *to_nxt++ = static_cast<uint8_t>(t);
2553 }
2554 }
2555 return codecvt_base::ok;
2556}
2557
2558static
2559codecvt_base::result
2560utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2561 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2562 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2563{
2564 frm_nxt = frm;
2565 to_nxt = to;
2566 if (mode & consume_header)
2567 {
2568 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2569 frm_nxt += 2;
2570 }
2571 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2572 {
2573 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2574 if ((c1 & 0xFC00) == 0xDC00)
2575 return codecvt_base::error;
2576 if ((c1 & 0xFC00) != 0xD800)
2577 {
2578 if (c1 > Maxcode)
2579 return codecvt_base::error;
2580 *to_nxt = static_cast<uint32_t>(c1);
2581 frm_nxt += 2;
2582 }
2583 else
2584 {
2585 if (frm_end-frm_nxt < 4)
2586 return codecvt_base::partial;
2587 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2588 if ((c2 & 0xFC00) != 0xDC00)
2589 return codecvt_base::error;
2590 uint32_t t = static_cast<uint32_t>(
2591 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2592 | ((c1 & 0x003F) << 10)
2593 | (c2 & 0x03FF));
2594 if (t > Maxcode)
2595 return codecvt_base::error;
2596 *to_nxt = t;
2597 frm_nxt += 4;
2598 }
2599 }
2600 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2601}
2602
2603static
2604int
2605utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2606 size_t mx, unsigned long Maxcode = 0x10FFFF,
2607 codecvt_mode mode = codecvt_mode(0))
2608{
2609 const uint8_t* frm_nxt = frm;
2610 frm_nxt = frm;
2611 if (mode & consume_header)
2612 {
2613 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2614 frm_nxt += 2;
2615 }
2616 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2617 {
2618 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2619 if ((c1 & 0xFC00) == 0xDC00)
2620 break;
2621 if ((c1 & 0xFC00) != 0xD800)
2622 {
2623 if (c1 > Maxcode)
2624 break;
2625 frm_nxt += 2;
2626 }
2627 else
2628 {
2629 if (frm_end-frm_nxt < 4)
2630 break;
2631 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2632 if ((c2 & 0xFC00) != 0xDC00)
2633 break;
2634 uint32_t t = static_cast<uint32_t>(
2635 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2636 | ((c1 & 0x003F) << 10)
2637 | (c2 & 0x03FF));
2638 if (t > Maxcode)
2639 break;
2640 frm_nxt += 4;
2641 }
2642 }
2643 return static_cast<int>(frm_nxt - frm);
2644}
2645
2646static
2647codecvt_base::result
2648ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2649 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2650 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2651{
2652 frm_nxt = frm;
2653 to_nxt = to;
2654 if (mode & generate_header)
2655 {
2656 if (to_end-to_nxt < 2)
2657 return codecvt_base::partial;
2658 *to_nxt++ = static_cast<uint8_t>(0xFF);
2659 *to_nxt++ = static_cast<uint8_t>(0xFE);
2660 }
2661 for (; frm_nxt < frm_end; ++frm_nxt)
2662 {
2663 uint32_t wc = *frm_nxt;
2664 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2665 return codecvt_base::error;
2666 if (wc < 0x010000)
2667 {
2668 if (to_end-to_nxt < 2)
2669 return codecvt_base::partial;
2670 *to_nxt++ = static_cast<uint8_t>(wc);
2671 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2672 }
2673 else
2674 {
2675 if (to_end-to_nxt < 4)
2676 return codecvt_base::partial;
2677 uint16_t t = static_cast<uint16_t>(
2678 0xD800
2679 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2680 | ((wc & 0x00FC00) >> 10));
2681 *to_nxt++ = static_cast<uint8_t>(t);
2682 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2683 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2684 *to_nxt++ = static_cast<uint8_t>(t);
2685 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2686 }
2687 }
2688 return codecvt_base::ok;
2689}
2690
2691static
2692codecvt_base::result
2693utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2694 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2695 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2696{
2697 frm_nxt = frm;
2698 to_nxt = to;
2699 if (mode & consume_header)
2700 {
2701 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2702 frm_nxt += 2;
2703 }
2704 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2705 {
2706 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2707 if ((c1 & 0xFC00) == 0xDC00)
2708 return codecvt_base::error;
2709 if ((c1 & 0xFC00) != 0xD800)
2710 {
2711 if (c1 > Maxcode)
2712 return codecvt_base::error;
2713 *to_nxt = static_cast<uint32_t>(c1);
2714 frm_nxt += 2;
2715 }
2716 else
2717 {
2718 if (frm_end-frm_nxt < 4)
2719 return codecvt_base::partial;
2720 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2721 if ((c2 & 0xFC00) != 0xDC00)
2722 return codecvt_base::error;
2723 uint32_t t = static_cast<uint32_t>(
2724 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2725 | ((c1 & 0x003F) << 10)
2726 | (c2 & 0x03FF));
2727 if (t > Maxcode)
2728 return codecvt_base::error;
2729 *to_nxt = t;
2730 frm_nxt += 4;
2731 }
2732 }
2733 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2734}
2735
2736static
2737int
2738utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2739 size_t mx, unsigned long Maxcode = 0x10FFFF,
2740 codecvt_mode mode = codecvt_mode(0))
2741{
2742 const uint8_t* frm_nxt = frm;
2743 frm_nxt = frm;
2744 if (mode & consume_header)
2745 {
2746 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2747 frm_nxt += 2;
2748 }
2749 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2750 {
2751 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2752 if ((c1 & 0xFC00) == 0xDC00)
2753 break;
2754 if ((c1 & 0xFC00) != 0xD800)
2755 {
2756 if (c1 > Maxcode)
2757 break;
2758 frm_nxt += 2;
2759 }
2760 else
2761 {
2762 if (frm_end-frm_nxt < 4)
2763 break;
2764 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2765 if ((c2 & 0xFC00) != 0xDC00)
2766 break;
2767 uint32_t t = static_cast<uint32_t>(
2768 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2769 | ((c1 & 0x003F) << 10)
2770 | (c2 & 0x03FF));
2771 if (t > Maxcode)
2772 break;
2773 frm_nxt += 4;
2774 }
2775 }
2776 return static_cast<int>(frm_nxt - frm);
2777}
2778
2779static
2780codecvt_base::result
2781ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2782 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2783 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2784{
2785 frm_nxt = frm;
2786 to_nxt = to;
2787 if (mode & generate_header)
2788 {
2789 if (to_end-to_nxt < 2)
2790 return codecvt_base::partial;
2791 *to_nxt++ = static_cast<uint8_t>(0xFE);
2792 *to_nxt++ = static_cast<uint8_t>(0xFF);
2793 }
2794 for (; frm_nxt < frm_end; ++frm_nxt)
2795 {
2796 uint16_t wc = *frm_nxt;
2797 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2798 return codecvt_base::error;
2799 if (to_end-to_nxt < 2)
2800 return codecvt_base::partial;
2801 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2802 *to_nxt++ = static_cast<uint8_t>(wc);
2803 }
2804 return codecvt_base::ok;
2805}
2806
2807static
2808codecvt_base::result
2809utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2810 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2811 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2812{
2813 frm_nxt = frm;
2814 to_nxt = to;
2815 if (mode & consume_header)
2816 {
2817 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2818 frm_nxt += 2;
2819 }
2820 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2821 {
2822 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2823 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2824 return codecvt_base::error;
2825 *to_nxt = c1;
2826 frm_nxt += 2;
2827 }
2828 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2829}
2830
2831static
2832int
2833utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2834 size_t mx, unsigned long Maxcode = 0x10FFFF,
2835 codecvt_mode mode = codecvt_mode(0))
2836{
2837 const uint8_t* frm_nxt = frm;
2838 frm_nxt = frm;
2839 if (mode & consume_header)
2840 {
2841 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2842 frm_nxt += 2;
2843 }
2844 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2845 {
2846 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2847 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2848 break;
2849 frm_nxt += 2;
2850 }
2851 return static_cast<int>(frm_nxt - frm);
2852}
2853
2854static
2855codecvt_base::result
2856ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2857 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2858 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2859{
2860 frm_nxt = frm;
2861 to_nxt = to;
2862 if (mode & generate_header)
2863 {
2864 if (to_end-to_nxt < 2)
2865 return codecvt_base::partial;
2866 *to_nxt++ = static_cast<uint8_t>(0xFF);
2867 *to_nxt++ = static_cast<uint8_t>(0xFE);
2868 }
2869 for (; frm_nxt < frm_end; ++frm_nxt)
2870 {
2871 uint16_t wc = *frm_nxt;
2872 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2873 return codecvt_base::error;
2874 if (to_end-to_nxt < 2)
2875 return codecvt_base::partial;
2876 *to_nxt++ = static_cast<uint8_t>(wc);
2877 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2878 }
2879 return codecvt_base::ok;
2880}
2881
2882static
2883codecvt_base::result
2884utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2885 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2886 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2887{
2888 frm_nxt = frm;
2889 to_nxt = to;
2890 if (mode & consume_header)
2891 {
2892 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2893 frm_nxt += 2;
2894 }
2895 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2896 {
2897 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2898 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2899 return codecvt_base::error;
2900 *to_nxt = c1;
2901 frm_nxt += 2;
2902 }
2903 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2904}
2905
2906static
2907int
2908utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2909 size_t mx, unsigned long Maxcode = 0x10FFFF,
2910 codecvt_mode mode = codecvt_mode(0))
2911{
2912 const uint8_t* frm_nxt = frm;
2913 frm_nxt = frm;
2914 if (mode & consume_header)
2915 {
2916 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2917 frm_nxt += 2;
2918 }
2919 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2920 {
2921 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2922 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2923 break;
2924 frm_nxt += 2;
2925 }
2926 return static_cast<int>(frm_nxt - frm);
2927}
2928
Howard Hinnantc51e1022010-05-11 19:42:16 +00002929// template <> class codecvt<char16_t, char, mbstate_t>
2930
Howard Hinnantffb308e2010-08-22 00:03:27 +00002931locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002932
2933codecvt<char16_t, char, mbstate_t>::~codecvt()
2934{
2935}
2936
2937codecvt<char16_t, char, mbstate_t>::result
2938codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnantffb308e2010-08-22 00:03:27 +00002939 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002940 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2941{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00002942 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2943 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2944 const uint16_t* _frm_nxt = _frm;
2945 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2946 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2947 uint8_t* _to_nxt = _to;
2948 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2949 frm_nxt = frm + (_frm_nxt - _frm);
2950 to_nxt = to + (_to_nxt - _to);
2951 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002952}
2953
2954codecvt<char16_t, char, mbstate_t>::result
2955codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnantffb308e2010-08-22 00:03:27 +00002956 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002957 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2958{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00002959 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2960 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2961 const uint8_t* _frm_nxt = _frm;
2962 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2963 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2964 uint16_t* _to_nxt = _to;
2965 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2966 frm_nxt = frm + (_frm_nxt - _frm);
2967 to_nxt = to + (_to_nxt - _to);
2968 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002969}
2970
2971codecvt<char16_t, char, mbstate_t>::result
2972codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2973 extern_type* to, extern_type*, extern_type*& to_nxt) const
2974{
2975 to_nxt = to;
2976 return noconv;
2977}
2978
2979int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00002980codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002981{
2982 return 0;
2983}
2984
2985bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00002986codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00002987{
2988 return false;
2989}
2990
2991int
2992codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2993 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2994{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00002995 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2996 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2997 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002998}
2999
3000int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003001codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003002{
3003 return 4;
3004}
3005
3006// template <> class codecvt<char32_t, char, mbstate_t>
3007
Howard Hinnantffb308e2010-08-22 00:03:27 +00003008locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003009
3010codecvt<char32_t, char, mbstate_t>::~codecvt()
3011{
3012}
3013
3014codecvt<char32_t, char, mbstate_t>::result
3015codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnantffb308e2010-08-22 00:03:27 +00003016 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003017 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3018{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003019 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3020 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3021 const uint32_t* _frm_nxt = _frm;
3022 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3023 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3024 uint8_t* _to_nxt = _to;
3025 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3026 frm_nxt = frm + (_frm_nxt - _frm);
3027 to_nxt = to + (_to_nxt - _to);
3028 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003029}
3030
3031codecvt<char32_t, char, mbstate_t>::result
3032codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnantffb308e2010-08-22 00:03:27 +00003033 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003034 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3035{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003036 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3037 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3038 const uint8_t* _frm_nxt = _frm;
3039 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3040 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3041 uint32_t* _to_nxt = _to;
3042 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3043 frm_nxt = frm + (_frm_nxt - _frm);
3044 to_nxt = to + (_to_nxt - _to);
3045 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003046}
3047
3048codecvt<char32_t, char, mbstate_t>::result
3049codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3050 extern_type* to, extern_type*, extern_type*& to_nxt) const
3051{
3052 to_nxt = to;
3053 return noconv;
3054}
3055
3056int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003057codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003058{
3059 return 0;
3060}
3061
3062bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003063codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003064{
3065 return false;
3066}
3067
3068int
3069codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3070 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3071{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003072 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3073 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3074 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003075}
3076
3077int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003078codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003079{
3080 return 4;
3081}
3082
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003083// __codecvt_utf8<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00003084
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003085__codecvt_utf8<wchar_t>::result
3086__codecvt_utf8<wchar_t>::do_out(state_type&,
3087 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003088 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3089{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003090 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3091 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3092 const uint32_t* _frm_nxt = _frm;
3093 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3094 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3095 uint8_t* _to_nxt = _to;
3096 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3097 _Maxcode_, _Mode_);
3098 frm_nxt = frm + (_frm_nxt - _frm);
3099 to_nxt = to + (_to_nxt - _to);
3100 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003101}
3102
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003103__codecvt_utf8<wchar_t>::result
3104__codecvt_utf8<wchar_t>::do_in(state_type&,
3105 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003106 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3107{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003108 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3109 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3110 const uint8_t* _frm_nxt = _frm;
3111 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3112 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3113 uint32_t* _to_nxt = _to;
3114 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3115 _Maxcode_, _Mode_);
3116 frm_nxt = frm + (_frm_nxt - _frm);
3117 to_nxt = to + (_to_nxt - _to);
3118 return r;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003119}
3120
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003121__codecvt_utf8<wchar_t>::result
3122__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003123 extern_type* to, extern_type*, extern_type*& to_nxt) const
3124{
3125 to_nxt = to;
3126 return noconv;
3127}
3128
3129int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003130__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003131{
3132 return 0;
3133}
3134
3135bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003136__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003137{
3138 return false;
3139}
3140
3141int
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003142__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnantc51e1022010-05-11 19:42:16 +00003143 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3144{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003145 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3146 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3147 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003148}
3149
3150int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003151__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00003152{
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003153 if (_Mode_ & consume_header)
3154 return 7;
3155 return 4;
3156}
3157
3158// __codecvt_utf8<char16_t>
3159
3160__codecvt_utf8<char16_t>::result
3161__codecvt_utf8<char16_t>::do_out(state_type&,
3162 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3163 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3164{
3165 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3166 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3167 const uint16_t* _frm_nxt = _frm;
3168 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3169 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3170 uint8_t* _to_nxt = _to;
3171 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3172 _Maxcode_, _Mode_);
3173 frm_nxt = frm + (_frm_nxt - _frm);
3174 to_nxt = to + (_to_nxt - _to);
3175 return r;
3176}
3177
3178__codecvt_utf8<char16_t>::result
3179__codecvt_utf8<char16_t>::do_in(state_type&,
3180 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3181 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3182{
3183 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3184 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3185 const uint8_t* _frm_nxt = _frm;
3186 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3187 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3188 uint16_t* _to_nxt = _to;
3189 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3190 _Maxcode_, _Mode_);
3191 frm_nxt = frm + (_frm_nxt - _frm);
3192 to_nxt = to + (_to_nxt - _to);
3193 return r;
3194}
3195
3196__codecvt_utf8<char16_t>::result
3197__codecvt_utf8<char16_t>::do_unshift(state_type&,
3198 extern_type* to, extern_type*, extern_type*& to_nxt) const
3199{
3200 to_nxt = to;
3201 return noconv;
3202}
3203
3204int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003205__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003206{
3207 return 0;
3208}
3209
3210bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003211__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003212{
3213 return false;
3214}
3215
3216int
3217__codecvt_utf8<char16_t>::do_length(state_type&,
3218 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3219{
3220 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3221 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3222 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3223}
3224
3225int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003226__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003227{
3228 if (_Mode_ & consume_header)
3229 return 6;
3230 return 3;
3231}
3232
3233// __codecvt_utf8<char32_t>
3234
3235__codecvt_utf8<char32_t>::result
3236__codecvt_utf8<char32_t>::do_out(state_type&,
3237 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3238 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3239{
3240 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3241 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3242 const uint32_t* _frm_nxt = _frm;
3243 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3244 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3245 uint8_t* _to_nxt = _to;
3246 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3247 _Maxcode_, _Mode_);
3248 frm_nxt = frm + (_frm_nxt - _frm);
3249 to_nxt = to + (_to_nxt - _to);
3250 return r;
3251}
3252
3253__codecvt_utf8<char32_t>::result
3254__codecvt_utf8<char32_t>::do_in(state_type&,
3255 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3256 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3257{
3258 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3259 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3260 const uint8_t* _frm_nxt = _frm;
3261 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3262 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3263 uint32_t* _to_nxt = _to;
3264 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3265 _Maxcode_, _Mode_);
3266 frm_nxt = frm + (_frm_nxt - _frm);
3267 to_nxt = to + (_to_nxt - _to);
3268 return r;
3269}
3270
3271__codecvt_utf8<char32_t>::result
3272__codecvt_utf8<char32_t>::do_unshift(state_type&,
3273 extern_type* to, extern_type*, extern_type*& to_nxt) const
3274{
3275 to_nxt = to;
3276 return noconv;
3277}
3278
3279int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003280__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003281{
3282 return 0;
3283}
3284
3285bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003286__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003287{
3288 return false;
3289}
3290
3291int
3292__codecvt_utf8<char32_t>::do_length(state_type&,
3293 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3294{
3295 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3296 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3297 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3298}
3299
3300int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003301__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003302{
3303 if (_Mode_ & consume_header)
3304 return 7;
3305 return 4;
3306}
3307
3308// __codecvt_utf16<wchar_t, false>
3309
3310__codecvt_utf16<wchar_t, false>::result
3311__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3312 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3313 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3314{
3315 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3316 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3317 const uint32_t* _frm_nxt = _frm;
3318 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3319 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3320 uint8_t* _to_nxt = _to;
3321 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3322 _Maxcode_, _Mode_);
3323 frm_nxt = frm + (_frm_nxt - _frm);
3324 to_nxt = to + (_to_nxt - _to);
3325 return r;
3326}
3327
3328__codecvt_utf16<wchar_t, false>::result
3329__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3330 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3331 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3332{
3333 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3334 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3335 const uint8_t* _frm_nxt = _frm;
3336 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3337 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3338 uint32_t* _to_nxt = _to;
3339 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3340 _Maxcode_, _Mode_);
3341 frm_nxt = frm + (_frm_nxt - _frm);
3342 to_nxt = to + (_to_nxt - _to);
3343 return r;
3344}
3345
3346__codecvt_utf16<wchar_t, false>::result
3347__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3348 extern_type* to, extern_type*, extern_type*& to_nxt) const
3349{
3350 to_nxt = to;
3351 return noconv;
3352}
3353
3354int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003355__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003356{
3357 return 0;
3358}
3359
3360bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003361__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003362{
3363 return false;
3364}
3365
3366int
3367__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3368 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3369{
3370 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3371 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3372 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3373}
3374
3375int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003376__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003377{
3378 if (_Mode_ & consume_header)
3379 return 6;
3380 return 4;
3381}
3382
3383// __codecvt_utf16<wchar_t, true>
3384
3385__codecvt_utf16<wchar_t, true>::result
3386__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3387 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3388 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3389{
3390 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3391 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3392 const uint32_t* _frm_nxt = _frm;
3393 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3394 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3395 uint8_t* _to_nxt = _to;
3396 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3397 _Maxcode_, _Mode_);
3398 frm_nxt = frm + (_frm_nxt - _frm);
3399 to_nxt = to + (_to_nxt - _to);
3400 return r;
3401}
3402
3403__codecvt_utf16<wchar_t, true>::result
3404__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3405 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3406 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3407{
3408 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3409 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3410 const uint8_t* _frm_nxt = _frm;
3411 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3412 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3413 uint32_t* _to_nxt = _to;
3414 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3415 _Maxcode_, _Mode_);
3416 frm_nxt = frm + (_frm_nxt - _frm);
3417 to_nxt = to + (_to_nxt - _to);
3418 return r;
3419}
3420
3421__codecvt_utf16<wchar_t, true>::result
3422__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3423 extern_type* to, extern_type*, extern_type*& to_nxt) const
3424{
3425 to_nxt = to;
3426 return noconv;
3427}
3428
3429int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003430__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003431{
3432 return 0;
3433}
3434
3435bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003436__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003437{
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003438 return false;
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003439}
3440
3441int
3442__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3443 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3444{
3445 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3446 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3447 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3448}
3449
3450int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003451__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003452{
3453 if (_Mode_ & consume_header)
3454 return 6;
3455 return 4;
3456}
3457
3458// __codecvt_utf16<char16_t, false>
3459
3460__codecvt_utf16<char16_t, false>::result
3461__codecvt_utf16<char16_t, false>::do_out(state_type&,
3462 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3463 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3464{
3465 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3466 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3467 const uint16_t* _frm_nxt = _frm;
3468 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3469 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3470 uint8_t* _to_nxt = _to;
3471 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3472 _Maxcode_, _Mode_);
3473 frm_nxt = frm + (_frm_nxt - _frm);
3474 to_nxt = to + (_to_nxt - _to);
3475 return r;
3476}
3477
3478__codecvt_utf16<char16_t, false>::result
3479__codecvt_utf16<char16_t, false>::do_in(state_type&,
3480 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3481 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3482{
3483 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3484 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3485 const uint8_t* _frm_nxt = _frm;
3486 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3487 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3488 uint16_t* _to_nxt = _to;
3489 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3490 _Maxcode_, _Mode_);
3491 frm_nxt = frm + (_frm_nxt - _frm);
3492 to_nxt = to + (_to_nxt - _to);
3493 return r;
3494}
3495
3496__codecvt_utf16<char16_t, false>::result
3497__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3498 extern_type* to, extern_type*, extern_type*& to_nxt) const
3499{
3500 to_nxt = to;
3501 return noconv;
3502}
3503
3504int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003505__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003506{
3507 return 0;
3508}
3509
3510bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003511__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003512{
3513 return false;
3514}
3515
3516int
3517__codecvt_utf16<char16_t, false>::do_length(state_type&,
3518 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3519{
3520 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3521 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3522 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3523}
3524
3525int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003526__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003527{
3528 if (_Mode_ & consume_header)
3529 return 4;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003530 return 2;
3531}
3532
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003533// __codecvt_utf16<char16_t, true>
3534
3535__codecvt_utf16<char16_t, true>::result
3536__codecvt_utf16<char16_t, true>::do_out(state_type&,
3537 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3538 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3539{
3540 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3541 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3542 const uint16_t* _frm_nxt = _frm;
3543 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3544 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3545 uint8_t* _to_nxt = _to;
3546 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3547 _Maxcode_, _Mode_);
3548 frm_nxt = frm + (_frm_nxt - _frm);
3549 to_nxt = to + (_to_nxt - _to);
3550 return r;
3551}
3552
3553__codecvt_utf16<char16_t, true>::result
3554__codecvt_utf16<char16_t, true>::do_in(state_type&,
3555 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3556 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3557{
3558 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3559 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3560 const uint8_t* _frm_nxt = _frm;
3561 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3562 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3563 uint16_t* _to_nxt = _to;
3564 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3565 _Maxcode_, _Mode_);
3566 frm_nxt = frm + (_frm_nxt - _frm);
3567 to_nxt = to + (_to_nxt - _to);
3568 return r;
3569}
3570
3571__codecvt_utf16<char16_t, true>::result
3572__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3573 extern_type* to, extern_type*, extern_type*& to_nxt) const
3574{
3575 to_nxt = to;
3576 return noconv;
3577}
3578
3579int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003580__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003581{
3582 return 0;
3583}
3584
3585bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003586__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003587{
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003588 return false;
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003589}
3590
3591int
3592__codecvt_utf16<char16_t, true>::do_length(state_type&,
3593 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3594{
3595 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3596 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3597 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3598}
3599
3600int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003601__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003602{
3603 if (_Mode_ & consume_header)
3604 return 4;
3605 return 2;
3606}
3607
3608// __codecvt_utf16<char32_t, false>
3609
3610__codecvt_utf16<char32_t, false>::result
3611__codecvt_utf16<char32_t, false>::do_out(state_type&,
3612 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3613 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3614{
3615 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3616 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3617 const uint32_t* _frm_nxt = _frm;
3618 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3619 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3620 uint8_t* _to_nxt = _to;
3621 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3622 _Maxcode_, _Mode_);
3623 frm_nxt = frm + (_frm_nxt - _frm);
3624 to_nxt = to + (_to_nxt - _to);
3625 return r;
3626}
3627
3628__codecvt_utf16<char32_t, false>::result
3629__codecvt_utf16<char32_t, false>::do_in(state_type&,
3630 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3631 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3632{
3633 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3634 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3635 const uint8_t* _frm_nxt = _frm;
3636 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3637 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3638 uint32_t* _to_nxt = _to;
3639 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3640 _Maxcode_, _Mode_);
3641 frm_nxt = frm + (_frm_nxt - _frm);
3642 to_nxt = to + (_to_nxt - _to);
3643 return r;
3644}
3645
3646__codecvt_utf16<char32_t, false>::result
3647__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3648 extern_type* to, extern_type*, extern_type*& to_nxt) const
3649{
3650 to_nxt = to;
3651 return noconv;
3652}
3653
3654int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003655__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003656{
3657 return 0;
3658}
3659
3660bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003661__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003662{
3663 return false;
3664}
3665
3666int
3667__codecvt_utf16<char32_t, false>::do_length(state_type&,
3668 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3669{
3670 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3671 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3672 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3673}
3674
3675int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003676__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003677{
3678 if (_Mode_ & consume_header)
3679 return 6;
3680 return 4;
3681}
3682
3683// __codecvt_utf16<char32_t, true>
3684
3685__codecvt_utf16<char32_t, true>::result
3686__codecvt_utf16<char32_t, true>::do_out(state_type&,
3687 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3688 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3689{
3690 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3691 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3692 const uint32_t* _frm_nxt = _frm;
3693 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3694 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3695 uint8_t* _to_nxt = _to;
3696 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3697 _Maxcode_, _Mode_);
3698 frm_nxt = frm + (_frm_nxt - _frm);
3699 to_nxt = to + (_to_nxt - _to);
3700 return r;
3701}
3702
3703__codecvt_utf16<char32_t, true>::result
3704__codecvt_utf16<char32_t, true>::do_in(state_type&,
3705 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3706 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3707{
3708 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3709 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3710 const uint8_t* _frm_nxt = _frm;
3711 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3712 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3713 uint32_t* _to_nxt = _to;
3714 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3715 _Maxcode_, _Mode_);
3716 frm_nxt = frm + (_frm_nxt - _frm);
3717 to_nxt = to + (_to_nxt - _to);
3718 return r;
3719}
3720
3721__codecvt_utf16<char32_t, true>::result
3722__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3723 extern_type* to, extern_type*, extern_type*& to_nxt) const
3724{
3725 to_nxt = to;
3726 return noconv;
3727}
3728
3729int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003730__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003731{
3732 return 0;
3733}
3734
3735bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003736__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003737{
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003738 return false;
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003739}
3740
3741int
3742__codecvt_utf16<char32_t, true>::do_length(state_type&,
3743 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3744{
3745 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3746 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3747 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3748}
3749
3750int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003751__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003752{
3753 if (_Mode_ & consume_header)
3754 return 6;
3755 return 4;
3756}
3757
3758// __codecvt_utf8_utf16<wchar_t>
3759
3760__codecvt_utf8_utf16<wchar_t>::result
3761__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3762 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3763 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3764{
3765 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3766 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3767 const uint32_t* _frm_nxt = _frm;
3768 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3769 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3770 uint8_t* _to_nxt = _to;
3771 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3772 _Maxcode_, _Mode_);
3773 frm_nxt = frm + (_frm_nxt - _frm);
3774 to_nxt = to + (_to_nxt - _to);
3775 return r;
3776}
3777
3778__codecvt_utf8_utf16<wchar_t>::result
3779__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3780 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3781 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3782{
3783 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3784 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3785 const uint8_t* _frm_nxt = _frm;
3786 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3787 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3788 uint32_t* _to_nxt = _to;
3789 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3790 _Maxcode_, _Mode_);
3791 frm_nxt = frm + (_frm_nxt - _frm);
3792 to_nxt = to + (_to_nxt - _to);
3793 return r;
3794}
3795
3796__codecvt_utf8_utf16<wchar_t>::result
3797__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3798 extern_type* to, extern_type*, extern_type*& to_nxt) const
3799{
3800 to_nxt = to;
3801 return noconv;
3802}
3803
3804int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003805__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003806{
3807 return 0;
3808}
3809
3810bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003811__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003812{
3813 return false;
3814}
3815
3816int
3817__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3818 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3819{
3820 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3821 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3822 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3823}
3824
3825int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003826__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003827{
3828 if (_Mode_ & consume_header)
3829 return 7;
3830 return 4;
3831}
3832
3833// __codecvt_utf8_utf16<char16_t>
3834
3835__codecvt_utf8_utf16<char16_t>::result
3836__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3837 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3838 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3839{
3840 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3841 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3842 const uint16_t* _frm_nxt = _frm;
3843 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3844 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3845 uint8_t* _to_nxt = _to;
3846 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3847 _Maxcode_, _Mode_);
3848 frm_nxt = frm + (_frm_nxt - _frm);
3849 to_nxt = to + (_to_nxt - _to);
3850 return r;
3851}
3852
3853__codecvt_utf8_utf16<char16_t>::result
3854__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3855 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3856 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3857{
3858 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3859 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3860 const uint8_t* _frm_nxt = _frm;
3861 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3862 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3863 uint16_t* _to_nxt = _to;
3864 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3865 _Maxcode_, _Mode_);
3866 frm_nxt = frm + (_frm_nxt - _frm);
3867 to_nxt = to + (_to_nxt - _to);
3868 return r;
3869}
3870
3871__codecvt_utf8_utf16<char16_t>::result
3872__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3873 extern_type* to, extern_type*, extern_type*& to_nxt) const
3874{
3875 to_nxt = to;
3876 return noconv;
3877}
3878
3879int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003880__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003881{
3882 return 0;
3883}
3884
3885bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003886__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003887{
3888 return false;
3889}
3890
3891int
3892__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3893 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3894{
3895 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3896 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3897 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3898}
3899
3900int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003901__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003902{
3903 if (_Mode_ & consume_header)
3904 return 7;
3905 return 4;
3906}
3907
3908// __codecvt_utf8_utf16<char32_t>
3909
3910__codecvt_utf8_utf16<char32_t>::result
3911__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3912 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3913 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3914{
3915 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3916 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3917 const uint32_t* _frm_nxt = _frm;
3918 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3919 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3920 uint8_t* _to_nxt = _to;
3921 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3922 _Maxcode_, _Mode_);
3923 frm_nxt = frm + (_frm_nxt - _frm);
3924 to_nxt = to + (_to_nxt - _to);
3925 return r;
3926}
3927
3928__codecvt_utf8_utf16<char32_t>::result
3929__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3930 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3931 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3932{
3933 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3934 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3935 const uint8_t* _frm_nxt = _frm;
3936 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3937 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3938 uint32_t* _to_nxt = _to;
3939 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3940 _Maxcode_, _Mode_);
3941 frm_nxt = frm + (_frm_nxt - _frm);
3942 to_nxt = to + (_to_nxt - _to);
3943 return r;
3944}
3945
3946__codecvt_utf8_utf16<char32_t>::result
3947__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3948 extern_type* to, extern_type*, extern_type*& to_nxt) const
3949{
3950 to_nxt = to;
3951 return noconv;
3952}
3953
3954int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003955__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003956{
3957 return 0;
3958}
3959
3960bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003961__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003962{
3963 return false;
3964}
3965
3966int
3967__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3968 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3969{
3970 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3971 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3972 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3973}
3974
3975int
Howard Hinnant7c9e5732011-05-31 15:34:58 +00003976__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant7282c5a2010-05-30 21:39:41 +00003977{
3978 if (_Mode_ & consume_header)
3979 return 7;
3980 return 4;
3981}
3982
Howard Hinnantc51e1022010-05-11 19:42:16 +00003983// __narrow_to_utf8<16>
3984
3985__narrow_to_utf8<16>::~__narrow_to_utf8()
3986{
3987}
3988
3989// __narrow_to_utf8<32>
3990
3991__narrow_to_utf8<32>::~__narrow_to_utf8()
3992{
3993}
3994
3995// __widen_from_utf8<16>
3996
3997__widen_from_utf8<16>::~__widen_from_utf8()
3998{
3999}
4000
4001// __widen_from_utf8<32>
4002
4003__widen_from_utf8<32>::~__widen_from_utf8()
4004{
4005}
4006
4007// numpunct<char> && numpunct<wchar_t>
4008
4009locale::id numpunct< char >::id;
4010locale::id numpunct<wchar_t>::id;
4011
4012numpunct<char>::numpunct(size_t refs)
4013 : locale::facet(refs),
4014 __decimal_point_('.'),
4015 __thousands_sep_(',')
4016{
4017}
4018
4019numpunct<wchar_t>::numpunct(size_t refs)
4020 : locale::facet(refs),
4021 __decimal_point_(L'.'),
4022 __thousands_sep_(L',')
4023{
4024}
4025
4026numpunct<char>::~numpunct()
4027{
4028}
4029
4030numpunct<wchar_t>::~numpunct()
4031{
4032}
4033
4034 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4035wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4036
4037 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4038wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4039
4040string numpunct< char >::do_grouping() const {return __grouping_;}
4041string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4042
4043 string numpunct< char >::do_truename() const {return "true";}
4044wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4045
4046 string numpunct< char >::do_falsename() const {return "false";}
4047wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4048
4049// numpunct_byname<char>
4050
4051numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4052 : numpunct<char>(refs)
4053{
4054 __init(nm);
4055}
4056
4057numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4058 : numpunct<char>(refs)
4059{
4060 __init(nm.c_str());
4061}
4062
4063numpunct_byname<char>::~numpunct_byname()
4064{
4065}
4066
4067void
4068numpunct_byname<char>::__init(const char* nm)
4069{
4070 if (strcmp(nm, "C") != 0)
4071 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004072 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00004073#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004074 if (loc == 0)
4075 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4076 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00004077#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004078#ifdef _LIBCPP_STABLE_APPLE_ABI
4079 lconv* lc = localeconv_l(loc.get());
4080#else
4081 lconv* lc = __localeconv_l(loc.get());
4082#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004083 if (*lc->decimal_point)
4084 __decimal_point_ = *lc->decimal_point;
4085 if (*lc->thousands_sep)
4086 __thousands_sep_ = *lc->thousands_sep;
4087 __grouping_ = lc->grouping;
Alexis Hunt920b4a22011-07-07 22:45:07 +00004088 // localization for truename and falsename is not available
Howard Hinnantc51e1022010-05-11 19:42:16 +00004089 }
4090}
4091
4092// numpunct_byname<wchar_t>
4093
4094numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4095 : numpunct<wchar_t>(refs)
4096{
4097 __init(nm);
4098}
4099
4100numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4101 : numpunct<wchar_t>(refs)
4102{
4103 __init(nm.c_str());
4104}
4105
4106numpunct_byname<wchar_t>::~numpunct_byname()
4107{
4108}
4109
4110void
4111numpunct_byname<wchar_t>::__init(const char* nm)
4112{
4113 if (strcmp(nm, "C") != 0)
4114 {
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004115 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00004116#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004117 if (loc == 0)
4118 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4119 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00004120#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004121#ifdef _LIBCPP_STABLE_APPLE_ABI
4122 lconv* lc = localeconv_l(loc.get());
4123#else
4124 lconv* lc = __localeconv_l(loc.get());
4125#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004126 if (*lc->decimal_point)
4127 __decimal_point_ = *lc->decimal_point;
4128 if (*lc->thousands_sep)
4129 __thousands_sep_ = *lc->thousands_sep;
4130 __grouping_ = lc->grouping;
4131 // locallization for truename and falsename is not available
4132 }
4133}
4134
4135// num_get helpers
4136
4137int
4138__num_get_base::__get_base(ios_base& iob)
4139{
4140 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4141 if (__basefield == ios_base::oct)
4142 return 8;
4143 else if (__basefield == ios_base::hex)
4144 return 16;
4145 else if (__basefield == 0)
4146 return 0;
4147 return 10;
4148}
4149
4150const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4151
4152void
4153__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4154 ios_base::iostate& __err)
4155{
4156 if (__grouping.size() != 0)
4157 {
4158 reverse(__g, __g_end);
4159 const char* __ig = __grouping.data();
4160 const char* __eg = __ig + __grouping.size();
4161 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4162 {
4163 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4164 {
4165 if (*__ig != *__r)
4166 {
4167 __err = ios_base::failbit;
4168 return;
4169 }
4170 }
4171 if (__eg - __ig > 1)
4172 ++__ig;
4173 }
4174 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4175 {
4176 if (*__ig < __g_end[-1] || __g_end[-1] == 0)
4177 __err = ios_base::failbit;
4178 }
4179 }
4180}
4181
4182void
4183__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4184 ios_base::fmtflags __flags)
4185{
4186 if (__flags & ios_base::showpos)
4187 *__fmtp++ = '+';
4188 if (__flags & ios_base::showbase)
4189 *__fmtp++ = '#';
4190 while(*__len)
4191 *__fmtp++ = *__len++;
4192 if ((__flags & ios_base::basefield) == ios_base::oct)
4193 *__fmtp = 'o';
4194 else if ((__flags & ios_base::basefield) == ios_base::hex)
4195 {
4196 if (__flags & ios_base::uppercase)
4197 *__fmtp = 'X';
4198 else
4199 *__fmtp = 'x';
4200 }
4201 else if (__signd)
4202 *__fmtp = 'd';
4203 else
4204 *__fmtp = 'u';
4205}
4206
4207bool
4208__num_put_base::__format_float(char* __fmtp, const char* __len,
4209 ios_base::fmtflags __flags)
4210{
4211 bool specify_precision = true;
4212 if (__flags & ios_base::showpos)
4213 *__fmtp++ = '+';
4214 if (__flags & ios_base::showpoint)
4215 *__fmtp++ = '#';
4216 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4217 bool uppercase = __flags & ios_base::uppercase;
4218 if (floatfield == (ios_base::fixed | ios_base::scientific))
4219 specify_precision = false;
4220 else
4221 {
4222 *__fmtp++ = '.';
4223 *__fmtp++ = '*';
4224 }
4225 while(*__len)
4226 *__fmtp++ = *__len++;
4227 if (floatfield == ios_base::fixed)
4228 {
4229 if (uppercase)
4230 *__fmtp = 'F';
4231 else
4232 *__fmtp = 'f';
4233 }
4234 else if (floatfield == ios_base::scientific)
4235 {
4236 if (uppercase)
4237 *__fmtp = 'E';
4238 else
4239 *__fmtp = 'e';
4240 }
4241 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4242 {
4243 if (uppercase)
4244 *__fmtp = 'A';
4245 else
4246 *__fmtp = 'a';
4247 }
4248 else
4249 {
4250 if (uppercase)
4251 *__fmtp = 'G';
4252 else
4253 *__fmtp = 'g';
4254 }
4255 return specify_precision;
4256}
4257
4258char*
4259__num_put_base::__identify_padding(char* __nb, char* __ne,
4260 const ios_base& __iob)
4261{
4262 switch (__iob.flags() & ios_base::adjustfield)
4263 {
4264 case ios_base::internal:
4265 if (__nb[0] == '-' || __nb[0] == '+')
4266 return __nb+1;
4267 if (__ne - __nb >= 2 && __nb[0] == '0'
4268 && (__nb[1] == 'x' || __nb[1] == 'X'))
4269 return __nb+2;
4270 break;
4271 case ios_base::left:
4272 return __ne;
4273 case ios_base::right:
4274 default:
4275 break;
4276 }
4277 return __nb;
4278}
4279
4280// time_get
4281
4282static
4283string*
4284init_weeks()
4285{
4286 static string weeks[14];
4287 weeks[0] = "Sunday";
4288 weeks[1] = "Monday";
4289 weeks[2] = "Tuesday";
4290 weeks[3] = "Wednesday";
4291 weeks[4] = "Thursday";
4292 weeks[5] = "Friday";
4293 weeks[6] = "Saturday";
4294 weeks[7] = "Sun";
4295 weeks[8] = "Mon";
4296 weeks[9] = "Tue";
4297 weeks[10] = "Wed";
4298 weeks[11] = "Thu";
4299 weeks[12] = "Fri";
4300 weeks[13] = "Sat";
4301 return weeks;
4302}
4303
4304static
4305wstring*
4306init_wweeks()
4307{
4308 static wstring weeks[14];
4309 weeks[0] = L"Sunday";
4310 weeks[1] = L"Monday";
4311 weeks[2] = L"Tuesday";
4312 weeks[3] = L"Wednesday";
4313 weeks[4] = L"Thursday";
4314 weeks[5] = L"Friday";
4315 weeks[6] = L"Saturday";
4316 weeks[7] = L"Sun";
4317 weeks[8] = L"Mon";
4318 weeks[9] = L"Tue";
4319 weeks[10] = L"Wed";
4320 weeks[11] = L"Thu";
4321 weeks[12] = L"Fri";
4322 weeks[13] = L"Sat";
4323 return weeks;
4324}
4325
4326template <>
4327const string*
4328__time_get_c_storage<char>::__weeks() const
4329{
4330 static const string* weeks = init_weeks();
4331 return weeks;
4332}
4333
4334template <>
4335const wstring*
4336__time_get_c_storage<wchar_t>::__weeks() const
4337{
4338 static const wstring* weeks = init_wweeks();
4339 return weeks;
4340}
4341
4342static
4343string*
4344init_months()
4345{
4346 static string months[24];
4347 months[0] = "January";
4348 months[1] = "February";
4349 months[2] = "March";
4350 months[3] = "April";
4351 months[4] = "May";
4352 months[5] = "June";
4353 months[6] = "July";
4354 months[7] = "August";
4355 months[8] = "September";
4356 months[9] = "October";
4357 months[10] = "November";
4358 months[11] = "December";
4359 months[12] = "Jan";
4360 months[13] = "Feb";
4361 months[14] = "Mar";
4362 months[15] = "Apr";
4363 months[16] = "May";
4364 months[17] = "Jun";
4365 months[18] = "Jul";
4366 months[19] = "Aug";
4367 months[20] = "Sep";
4368 months[21] = "Oct";
4369 months[22] = "Nov";
4370 months[23] = "Dec";
4371 return months;
4372}
4373
4374static
4375wstring*
4376init_wmonths()
4377{
4378 static wstring months[24];
4379 months[0] = L"January";
4380 months[1] = L"February";
4381 months[2] = L"March";
4382 months[3] = L"April";
4383 months[4] = L"May";
4384 months[5] = L"June";
4385 months[6] = L"July";
4386 months[7] = L"August";
4387 months[8] = L"September";
4388 months[9] = L"October";
4389 months[10] = L"November";
4390 months[11] = L"December";
4391 months[12] = L"Jan";
4392 months[13] = L"Feb";
4393 months[14] = L"Mar";
4394 months[15] = L"Apr";
4395 months[16] = L"May";
4396 months[17] = L"Jun";
4397 months[18] = L"Jul";
4398 months[19] = L"Aug";
4399 months[20] = L"Sep";
4400 months[21] = L"Oct";
4401 months[22] = L"Nov";
4402 months[23] = L"Dec";
4403 return months;
4404}
4405
4406template <>
4407const string*
4408__time_get_c_storage<char>::__months() const
4409{
4410 static const string* months = init_months();
4411 return months;
4412}
4413
4414template <>
4415const wstring*
4416__time_get_c_storage<wchar_t>::__months() const
4417{
4418 static const wstring* months = init_wmonths();
4419 return months;
4420}
4421
4422static
4423string*
4424init_am_pm()
4425{
4426 static string am_pm[24];
4427 am_pm[0] = "AM";
4428 am_pm[1] = "PM";
4429 return am_pm;
4430}
4431
4432static
4433wstring*
4434init_wam_pm()
4435{
4436 static wstring am_pm[24];
4437 am_pm[0] = L"AM";
4438 am_pm[1] = L"PM";
4439 return am_pm;
4440}
4441
4442template <>
4443const string*
4444__time_get_c_storage<char>::__am_pm() const
4445{
4446 static const string* am_pm = init_am_pm();
4447 return am_pm;
4448}
4449
4450template <>
4451const wstring*
4452__time_get_c_storage<wchar_t>::__am_pm() const
4453{
4454 static const wstring* am_pm = init_wam_pm();
4455 return am_pm;
4456}
4457
4458template <>
4459const string&
4460__time_get_c_storage<char>::__x() const
4461{
4462 static string s("%m/%d/%y");
4463 return s;
4464}
4465
4466template <>
4467const wstring&
4468__time_get_c_storage<wchar_t>::__x() const
4469{
4470 static wstring s(L"%m/%d/%y");
4471 return s;
4472}
4473
4474template <>
4475const string&
4476__time_get_c_storage<char>::__X() const
4477{
4478 static string s("%H:%M:%S");
4479 return s;
4480}
4481
4482template <>
4483const wstring&
4484__time_get_c_storage<wchar_t>::__X() const
4485{
4486 static wstring s(L"%H:%M:%S");
4487 return s;
4488}
4489
4490template <>
4491const string&
4492__time_get_c_storage<char>::__c() const
4493{
4494 static string s("%a %b %d %H:%M:%S %Y");
4495 return s;
4496}
4497
4498template <>
4499const wstring&
4500__time_get_c_storage<wchar_t>::__c() const
4501{
4502 static wstring s(L"%a %b %d %H:%M:%S %Y");
4503 return s;
4504}
4505
4506template <>
4507const string&
4508__time_get_c_storage<char>::__r() const
4509{
4510 static string s("%I:%M:%S %p");
4511 return s;
4512}
4513
4514template <>
4515const wstring&
4516__time_get_c_storage<wchar_t>::__r() const
4517{
4518 static wstring s(L"%I:%M:%S %p");
4519 return s;
4520}
4521
4522// time_get_byname
4523
4524__time_get::__time_get(const char* nm)
4525 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4526{
Howard Hinnant72f73582010-08-11 17:04:31 +00004527#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004528 if (__loc_ == 0)
4529 throw runtime_error("time_get_byname"
4530 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00004531#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004532}
4533
4534__time_get::__time_get(const string& nm)
4535 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4536{
Howard Hinnant72f73582010-08-11 17:04:31 +00004537#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004538 if (__loc_ == 0)
4539 throw runtime_error("time_get_byname"
4540 " failed to construct for " + nm);
Howard Hinnantffb308e2010-08-22 00:03:27 +00004541#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00004542}
4543
4544__time_get::~__time_get()
4545{
4546 freelocale(__loc_);
4547}
4548
4549template <>
4550string
4551__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4552{
4553 tm t;
4554 t.tm_sec = 59;
4555 t.tm_min = 55;
4556 t.tm_hour = 23;
4557 t.tm_mday = 31;
4558 t.tm_mon = 11;
4559 t.tm_year = 161;
4560 t.tm_wday = 6;
4561 t.tm_yday = 364;
4562 t.tm_isdst = -1;
4563 char buf[100];
4564 char f[3] = {0};
4565 f[0] = '%';
4566 f[1] = fmt;
4567 size_t n = strftime_l(buf, 100, f, &t, __loc_);
4568 char* bb = buf;
4569 char* be = buf + n;
4570 string result;
4571 while (bb != be)
4572 {
4573 if (ct.is(ctype_base::space, *bb))
4574 {
4575 result.push_back(' ');
4576 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4577 ;
4578 continue;
4579 }
4580 char* w = bb;
4581 ios_base::iostate err = ios_base::goodbit;
4582 int i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4583 ct, err, false)
4584 - this->__weeks_;
4585 if (i < 14)
4586 {
4587 result.push_back('%');
4588 if (i < 7)
4589 result.push_back('A');
4590 else
4591 result.push_back('a');
4592 bb = w;
4593 continue;
4594 }
4595 w = bb;
4596 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4597 ct, err, false)
4598 - this->__months_;
4599 if (i < 24)
4600 {
4601 result.push_back('%');
4602 if (i < 12)
4603 result.push_back('B');
4604 else
4605 result.push_back('b');
4606 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4607 result.back() = 'm';
4608 bb = w;
4609 continue;
4610 }
4611 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4612 {
4613 w = bb;
4614 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4615 ct, err, false) - this->__am_pm_;
4616 if (i < 2)
4617 {
4618 result.push_back('%');
4619 result.push_back('p');
4620 bb = w;
4621 continue;
4622 }
4623 }
4624 w = bb;
4625 if (ct.is(ctype_base::digit, *bb))
4626 {
4627 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4628 {
4629 case 6:
4630 result.push_back('%');
4631 result.push_back('w');
4632 break;
4633 case 7:
4634 result.push_back('%');
4635 result.push_back('u');
4636 break;
4637 case 11:
4638 result.push_back('%');
4639 result.push_back('I');
4640 break;
4641 case 12:
4642 result.push_back('%');
4643 result.push_back('m');
4644 break;
4645 case 23:
4646 result.push_back('%');
4647 result.push_back('H');
4648 break;
4649 case 31:
4650 result.push_back('%');
4651 result.push_back('d');
4652 break;
4653 case 55:
4654 result.push_back('%');
4655 result.push_back('M');
4656 break;
4657 case 59:
4658 result.push_back('%');
4659 result.push_back('S');
4660 break;
4661 case 61:
4662 result.push_back('%');
4663 result.push_back('y');
4664 break;
4665 case 364:
4666 result.push_back('%');
4667 result.push_back('j');
4668 break;
4669 case 2061:
4670 result.push_back('%');
4671 result.push_back('Y');
4672 break;
4673 default:
4674 for (; w != bb; ++w)
4675 result.push_back(*w);
4676 break;
4677 }
4678 continue;
4679 }
4680 if (*bb == '%')
4681 {
4682 result.push_back('%');
4683 result.push_back('%');
4684 ++bb;
4685 continue;
4686 }
4687 result.push_back(*bb);
4688 ++bb;
4689 }
4690 return result;
4691}
4692
4693template <>
4694wstring
4695__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4696{
4697 tm t;
4698 t.tm_sec = 59;
4699 t.tm_min = 55;
4700 t.tm_hour = 23;
4701 t.tm_mday = 31;
4702 t.tm_mon = 11;
4703 t.tm_year = 161;
4704 t.tm_wday = 6;
4705 t.tm_yday = 364;
4706 t.tm_isdst = -1;
4707 char buf[100];
4708 char f[3] = {0};
4709 f[0] = '%';
4710 f[1] = fmt;
4711 size_t be = strftime_l(buf, 100, f, &t, __loc_);
4712 wchar_t wbuf[100];
4713 wchar_t* wbb = wbuf;
4714 mbstate_t mb = {0};
4715 const char* bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004716#ifdef _LIBCPP_STABLE_APPLE_ABI
4717 size_t i = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4718#else
4719 size_t i = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4720#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004721 if (i == -1)
4722 __throw_runtime_error("locale not supported");
4723 wchar_t* wbe = wbb + i;
4724 wstring result;
4725 while (wbb != wbe)
4726 {
4727 if (ct.is(ctype_base::space, *wbb))
4728 {
4729 result.push_back(L' ');
4730 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4731 ;
4732 continue;
4733 }
4734 wchar_t* w = wbb;
4735 ios_base::iostate err = ios_base::goodbit;
4736 int i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4737 ct, err, false)
4738 - this->__weeks_;
4739 if (i < 14)
4740 {
4741 result.push_back(L'%');
4742 if (i < 7)
4743 result.push_back(L'A');
4744 else
4745 result.push_back(L'a');
4746 wbb = w;
4747 continue;
4748 }
4749 w = wbb;
4750 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4751 ct, err, false)
4752 - this->__months_;
4753 if (i < 24)
4754 {
4755 result.push_back(L'%');
4756 if (i < 12)
4757 result.push_back(L'B');
4758 else
4759 result.push_back(L'b');
4760 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4761 result.back() = L'm';
4762 wbb = w;
4763 continue;
4764 }
4765 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4766 {
4767 w = wbb;
4768 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4769 ct, err, false) - this->__am_pm_;
4770 if (i < 2)
4771 {
4772 result.push_back(L'%');
4773 result.push_back(L'p');
4774 wbb = w;
4775 continue;
4776 }
4777 }
4778 w = wbb;
4779 if (ct.is(ctype_base::digit, *wbb))
4780 {
4781 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4782 {
4783 case 6:
4784 result.push_back(L'%');
4785 result.push_back(L'w');
4786 break;
4787 case 7:
4788 result.push_back(L'%');
4789 result.push_back(L'u');
4790 break;
4791 case 11:
4792 result.push_back(L'%');
4793 result.push_back(L'I');
4794 break;
4795 case 12:
4796 result.push_back(L'%');
4797 result.push_back(L'm');
4798 break;
4799 case 23:
4800 result.push_back(L'%');
4801 result.push_back(L'H');
4802 break;
4803 case 31:
4804 result.push_back(L'%');
4805 result.push_back(L'd');
4806 break;
4807 case 55:
4808 result.push_back(L'%');
4809 result.push_back(L'M');
4810 break;
4811 case 59:
4812 result.push_back(L'%');
4813 result.push_back(L'S');
4814 break;
4815 case 61:
4816 result.push_back(L'%');
4817 result.push_back(L'y');
4818 break;
4819 case 364:
4820 result.push_back(L'%');
4821 result.push_back(L'j');
4822 break;
4823 case 2061:
4824 result.push_back(L'%');
4825 result.push_back(L'Y');
4826 break;
4827 default:
4828 for (; w != wbb; ++w)
4829 result.push_back(*w);
4830 break;
4831 }
4832 continue;
4833 }
4834 if (ct.narrow(*wbb, 0) == '%')
4835 {
4836 result.push_back(L'%');
4837 result.push_back(L'%');
4838 ++wbb;
4839 continue;
4840 }
4841 result.push_back(*wbb);
4842 ++wbb;
4843 }
4844 return result;
4845}
4846
4847template <>
4848void
4849__time_get_storage<char>::init(const ctype<char>& ct)
4850{
4851 tm t;
4852 char buf[100];
4853 // __weeks_
4854 for (int i = 0; i < 7; ++i)
4855 {
4856 t.tm_wday = i;
4857 strftime_l(buf, 100, "%A", &t, __loc_);
4858 __weeks_[i] = buf;
4859 strftime_l(buf, 100, "%a", &t, __loc_);
4860 __weeks_[i+7] = buf;
4861 }
4862 // __months_
4863 for (int i = 0; i < 12; ++i)
4864 {
4865 t.tm_mon = i;
4866 strftime_l(buf, 100, "%B", &t, __loc_);
4867 __months_[i] = buf;
4868 strftime_l(buf, 100, "%b", &t, __loc_);
4869 __months_[i+12] = buf;
4870 }
4871 // __am_pm_
4872 t.tm_hour = 1;
4873 strftime_l(buf, 100, "%p", &t, __loc_);
4874 __am_pm_[0] = buf;
4875 t.tm_hour = 13;
4876 strftime_l(buf, 100, "%p", &t, __loc_);
4877 __am_pm_[1] = buf;
4878 __c_ = __analyze('c', ct);
4879 __r_ = __analyze('r', ct);
4880 __x_ = __analyze('x', ct);
4881 __X_ = __analyze('X', ct);
4882}
4883
4884template <>
4885void
4886__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4887{
4888 tm t = {0};
4889 char buf[100];
4890 size_t be;
4891 wchar_t wbuf[100];
4892 wchar_t* wbe;
4893 mbstate_t mb = {0};
4894 // __weeks_
4895 for (int i = 0; i < 7; ++i)
4896 {
4897 t.tm_wday = i;
4898 be = strftime_l(buf, 100, "%A", &t, __loc_);
4899 mb = mbstate_t();
4900 const char* bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004901#ifdef _LIBCPP_STABLE_APPLE_ABI
4902 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4903#else
4904 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4905#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004906 if (j == -1)
4907 __throw_runtime_error("locale not supported");
4908 wbe = wbuf + j;
4909 __weeks_[i].assign(wbuf, wbe);
4910 be = strftime_l(buf, 100, "%a", &t, __loc_);
4911 mb = mbstate_t();
4912 bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004913#ifdef _LIBCPP_STABLE_APPLE_ABI
4914 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4915#else
4916 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4917#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004918 if (j == -1)
4919 __throw_runtime_error("locale not supported");
4920 wbe = wbuf + j;
4921 __weeks_[i+7].assign(wbuf, wbe);
4922 }
4923 // __months_
4924 for (int i = 0; i < 12; ++i)
4925 {
4926 t.tm_mon = i;
4927 be = strftime_l(buf, 100, "%B", &t, __loc_);
4928 mb = mbstate_t();
4929 const char* bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004930#ifdef _LIBCPP_STABLE_APPLE_ABI
4931 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4932#else
4933 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4934#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004935 if (j == -1)
4936 __throw_runtime_error("locale not supported");
4937 wbe = wbuf + j;
4938 __months_[i].assign(wbuf, wbe);
4939 be = strftime_l(buf, 100, "%b", &t, __loc_);
4940 mb = mbstate_t();
4941 bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004942#ifdef _LIBCPP_STABLE_APPLE_ABI
4943 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4944#else
4945 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4946#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004947 if (j == -1)
4948 __throw_runtime_error("locale not supported");
4949 wbe = wbuf + j;
4950 __months_[i+12].assign(wbuf, wbe);
4951 }
4952 // __am_pm_
4953 t.tm_hour = 1;
4954 be = strftime_l(buf, 100, "%p", &t, __loc_);
4955 mb = mbstate_t();
4956 const char* bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004957#ifdef _LIBCPP_STABLE_APPLE_ABI
4958 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4959#else
4960 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4961#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004962 if (j == -1)
4963 __throw_runtime_error("locale not supported");
4964 wbe = wbuf + j;
4965 __am_pm_[0].assign(wbuf, wbe);
4966 t.tm_hour = 13;
4967 be = strftime_l(buf, 100, "%p", &t, __loc_);
4968 mb = mbstate_t();
4969 bb = buf;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00004970#ifdef _LIBCPP_STABLE_APPLE_ABI
4971 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4972#else
4973 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4974#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00004975 if (j == -1)
4976 __throw_runtime_error("locale not supported");
4977 wbe = wbuf + j;
4978 __am_pm_[1].assign(wbuf, wbe);
4979 __c_ = __analyze('c', ct);
4980 __r_ = __analyze('r', ct);
4981 __x_ = __analyze('x', ct);
4982 __X_ = __analyze('X', ct);
4983}
4984
4985template <class CharT>
4986struct _LIBCPP_HIDDEN __time_get_temp
4987 : public ctype_byname<CharT>
4988{
4989 explicit __time_get_temp(const char* nm)
4990 : ctype_byname<CharT>(nm, 1) {}
4991 explicit __time_get_temp(const string& nm)
4992 : ctype_byname<CharT>(nm, 1) {}
4993};
4994
4995template <>
4996__time_get_storage<char>::__time_get_storage(const char* __nm)
4997 : __time_get(__nm)
4998{
4999 const __time_get_temp<char> ct(__nm);
5000 init(ct);
5001}
5002
5003template <>
5004__time_get_storage<char>::__time_get_storage(const string& __nm)
5005 : __time_get(__nm)
5006{
5007 const __time_get_temp<char> ct(__nm);
5008 init(ct);
5009}
5010
5011template <>
5012__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5013 : __time_get(__nm)
5014{
5015 const __time_get_temp<wchar_t> ct(__nm);
5016 init(ct);
5017}
5018
5019template <>
5020__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5021 : __time_get(__nm)
5022{
5023 const __time_get_temp<wchar_t> ct(__nm);
5024 init(ct);
5025}
5026
5027template <>
5028time_base::dateorder
5029__time_get_storage<char>::__do_date_order() const
5030{
5031 unsigned i;
5032 for (i = 0; i < __x_.size(); ++i)
5033 if (__x_[i] == '%')
5034 break;
5035 ++i;
5036 switch (__x_[i])
5037 {
5038 case 'y':
5039 case 'Y':
5040 for (++i; i < __x_.size(); ++i)
5041 if (__x_[i] == '%')
5042 break;
5043 if (i == __x_.size())
5044 break;
5045 ++i;
5046 switch (__x_[i])
5047 {
5048 case 'm':
5049 for (++i; i < __x_.size(); ++i)
5050 if (__x_[i] == '%')
5051 break;
5052 if (i == __x_.size())
5053 break;
5054 ++i;
5055 if (__x_[i] == 'd')
5056 return time_base::ymd;
5057 break;
5058 case 'd':
5059 for (++i; i < __x_.size(); ++i)
5060 if (__x_[i] == '%')
5061 break;
5062 if (i == __x_.size())
5063 break;
5064 ++i;
5065 if (__x_[i] == 'm')
5066 return time_base::ydm;
5067 break;
5068 }
5069 break;
5070 case 'm':
5071 for (++i; i < __x_.size(); ++i)
5072 if (__x_[i] == '%')
5073 break;
5074 if (i == __x_.size())
5075 break;
5076 ++i;
5077 if (__x_[i] == 'd')
5078 {
5079 for (++i; i < __x_.size(); ++i)
5080 if (__x_[i] == '%')
5081 break;
5082 if (i == __x_.size())
5083 break;
5084 ++i;
5085 if (__x_[i] == 'y' || __x_[i] == 'Y')
5086 return time_base::mdy;
5087 break;
5088 }
5089 break;
5090 case 'd':
5091 for (++i; i < __x_.size(); ++i)
5092 if (__x_[i] == '%')
5093 break;
5094 if (i == __x_.size())
5095 break;
5096 ++i;
5097 if (__x_[i] == 'm')
5098 {
5099 for (++i; i < __x_.size(); ++i)
5100 if (__x_[i] == '%')
5101 break;
5102 if (i == __x_.size())
5103 break;
5104 ++i;
5105 if (__x_[i] == 'y' || __x_[i] == 'Y')
5106 return time_base::dmy;
5107 break;
5108 }
5109 break;
5110 }
5111 return time_base::no_order;
5112}
5113
5114template <>
5115time_base::dateorder
5116__time_get_storage<wchar_t>::__do_date_order() const
5117{
5118 unsigned i;
5119 for (i = 0; i < __x_.size(); ++i)
5120 if (__x_[i] == L'%')
5121 break;
5122 ++i;
5123 switch (__x_[i])
5124 {
5125 case L'y':
5126 case L'Y':
5127 for (++i; i < __x_.size(); ++i)
5128 if (__x_[i] == L'%')
5129 break;
5130 if (i == __x_.size())
5131 break;
5132 ++i;
5133 switch (__x_[i])
5134 {
5135 case L'm':
5136 for (++i; i < __x_.size(); ++i)
5137 if (__x_[i] == L'%')
5138 break;
5139 if (i == __x_.size())
5140 break;
5141 ++i;
5142 if (__x_[i] == L'd')
5143 return time_base::ymd;
5144 break;
5145 case L'd':
5146 for (++i; i < __x_.size(); ++i)
5147 if (__x_[i] == L'%')
5148 break;
5149 if (i == __x_.size())
5150 break;
5151 ++i;
5152 if (__x_[i] == L'm')
5153 return time_base::ydm;
5154 break;
5155 }
5156 break;
5157 case L'm':
5158 for (++i; i < __x_.size(); ++i)
5159 if (__x_[i] == L'%')
5160 break;
5161 if (i == __x_.size())
5162 break;
5163 ++i;
5164 if (__x_[i] == L'd')
5165 {
5166 for (++i; i < __x_.size(); ++i)
5167 if (__x_[i] == L'%')
5168 break;
5169 if (i == __x_.size())
5170 break;
5171 ++i;
5172 if (__x_[i] == L'y' || __x_[i] == L'Y')
5173 return time_base::mdy;
5174 break;
5175 }
5176 break;
5177 case L'd':
5178 for (++i; i < __x_.size(); ++i)
5179 if (__x_[i] == L'%')
5180 break;
5181 if (i == __x_.size())
5182 break;
5183 ++i;
5184 if (__x_[i] == L'm')
5185 {
5186 for (++i; i < __x_.size(); ++i)
5187 if (__x_[i] == L'%')
5188 break;
5189 if (i == __x_.size())
5190 break;
5191 ++i;
5192 if (__x_[i] == L'y' || __x_[i] == L'Y')
5193 return time_base::dmy;
5194 break;
5195 }
5196 break;
5197 }
5198 return time_base::no_order;
5199}
5200
5201// time_put
5202
5203__time_put::__time_put(const char* nm)
5204 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5205{
Howard Hinnant72f73582010-08-11 17:04:31 +00005206#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005207 if (__loc_ == 0)
5208 throw runtime_error("time_put_byname"
5209 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00005210#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005211}
5212
5213__time_put::__time_put(const string& nm)
5214 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5215{
Howard Hinnant72f73582010-08-11 17:04:31 +00005216#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005217 if (__loc_ == 0)
5218 throw runtime_error("time_put_byname"
5219 " failed to construct for " + nm);
Howard Hinnantffb308e2010-08-22 00:03:27 +00005220#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005221}
5222
5223__time_put::~__time_put()
5224{
5225 if (__loc_)
5226 freelocale(__loc_);
5227}
5228
5229void
5230__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5231 char __fmt, char __mod) const
5232{
5233 char fmt[] = {'%', __fmt, __mod, 0};
5234 if (__mod != 0)
5235 swap(fmt[1], fmt[2]);
5236 size_t n = strftime_l(__nb, __ne-__nb, fmt, __tm, __loc_);
5237 __ne = __nb + n;
5238}
5239
5240void
5241__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5242 char __fmt, char __mod) const
5243{
5244 char __nar[100];
5245 char* __ne = __nar + 100;
5246 __do_put(__nar, __ne, __tm, __fmt, __mod);
5247 mbstate_t mb = {0};
5248 const char* __nb = __nar;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005249#ifdef _LIBCPP_STABLE_APPLE_ABI
5250 size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5251#else
5252 size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5253#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005254 if (j == -1)
5255 __throw_runtime_error("locale not supported");
5256 __we = __wb + j;
5257}
5258
5259// moneypunct_byname
5260
5261static
5262void
5263__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5264{
5265 const char sign = static_cast<char>(money_base::sign);
5266 const char space = static_cast<char>(money_base::space);
5267 const char none = static_cast<char>(money_base::none);
5268 const char symbol = static_cast<char>(money_base::symbol);
5269 const char value = static_cast<char>(money_base::value);
5270 switch (cs_precedes)
5271 {
5272 case 0:
5273 switch (sign_posn)
5274 {
5275 case 0:
5276 pat.field[0] = sign;
5277 pat.field[1] = value;
5278 pat.field[3] = symbol;
5279 switch (sep_by_space)
5280 {
5281 case 0:
5282 pat.field[2] = none;
5283 return;
5284 case 1:
5285 case 2:
5286 pat.field[2] = space;
5287 return;
5288 default:
5289 break;
5290 }
5291 break;
5292 case 1:
5293 pat.field[0] = sign;
5294 pat.field[3] = symbol;
5295 switch (sep_by_space)
5296 {
5297 case 0:
5298 pat.field[1] = value;
5299 pat.field[2] = none;
5300 return;
5301 case 1:
5302 pat.field[1] = value;
5303 pat.field[2] = space;
5304 return;
5305 case 2:
5306 pat.field[1] = space;
5307 pat.field[2] = value;
5308 return;
5309 default:
5310 break;
5311 }
5312 break;
5313 case 2:
5314 pat.field[0] = value;
5315 pat.field[3] = sign;
5316 switch (sep_by_space)
5317 {
5318 case 0:
5319 pat.field[1] = none;
5320 pat.field[2] = symbol;
5321 return;
5322 case 1:
5323 pat.field[1] = space;
5324 pat.field[2] = symbol;
5325 return;
5326 case 2:
5327 pat.field[1] = symbol;
5328 pat.field[2] = space;
5329 return;
5330 default:
5331 break;
5332 }
5333 break;
5334 case 3:
5335 pat.field[0] = value;
5336 pat.field[3] = symbol;
5337 switch (sep_by_space)
5338 {
5339 case 0:
5340 pat.field[1] = none;
5341 pat.field[2] = sign;
5342 return;
5343 case 1:
5344 pat.field[1] = space;
5345 pat.field[2] = sign;
5346 return;
5347 case 2:
5348 pat.field[1] = sign;
5349 pat.field[2] = space;
5350 return;
5351 default:
5352 break;
5353 }
5354 break;
5355 case 4:
5356 pat.field[0] = value;
5357 pat.field[3] = sign;
5358 switch (sep_by_space)
5359 {
5360 case 0:
5361 pat.field[1] = none;
5362 pat.field[2] = symbol;
5363 return;
5364 case 1:
5365 pat.field[1] = space;
5366 pat.field[2] = symbol;
5367 return;
5368 case 2:
5369 pat.field[1] = symbol;
5370 pat.field[2] = space;
5371 return;
5372 default:
5373 break;
5374 }
5375 break;
5376 default:
5377 break;
5378 }
5379 break;
5380 case 1:
5381 switch (sign_posn)
5382 {
5383 case 0:
5384 pat.field[0] = sign;
5385 pat.field[1] = symbol;
5386 pat.field[3] = value;
5387 switch (sep_by_space)
5388 {
5389 case 0:
5390 pat.field[2] = none;
5391 return;
5392 case 1:
5393 case 2:
5394 pat.field[2] = space;
5395 return;
5396 default:
5397 break;
5398 }
5399 break;
5400 case 1:
5401 pat.field[0] = sign;
5402 pat.field[3] = value;
5403 switch (sep_by_space)
5404 {
5405 case 0:
5406 pat.field[1] = symbol;
5407 pat.field[2] = none;
5408 return;
5409 case 1:
5410 pat.field[1] = symbol;
5411 pat.field[2] = space;
5412 return;
5413 case 2:
5414 pat.field[1] = space;
5415 pat.field[2] = symbol;
5416 return;
5417 default:
5418 break;
5419 }
5420 break;
5421 case 2:
5422 pat.field[0] = symbol;
5423 pat.field[3] = sign;
5424 switch (sep_by_space)
5425 {
5426 case 0:
5427 pat.field[1] = none;
5428 pat.field[2] = value;
5429 return;
5430 case 1:
5431 pat.field[1] = space;
5432 pat.field[2] = value;
5433 return;
5434 case 2:
5435 pat.field[1] = value;
5436 pat.field[2] = space;
5437 return;
5438 default:
5439 break;
5440 }
5441 break;
5442 case 3:
5443 pat.field[0] = sign;
5444 pat.field[3] = value;
5445 switch (sep_by_space)
5446 {
5447 case 0:
5448 pat.field[1] = symbol;
5449 pat.field[2] = none;
5450 return;
5451 case 1:
5452 pat.field[1] = symbol;
5453 pat.field[2] = space;
5454 return;
5455 case 2:
5456 pat.field[1] = space;
5457 pat.field[2] = symbol;
5458 return;
5459 default:
5460 break;
5461 }
5462 break;
5463 case 4:
5464 pat.field[0] = symbol;
5465 pat.field[3] = value;
5466 switch (sep_by_space)
5467 {
5468 case 0:
5469 pat.field[1] = sign;
5470 pat.field[2] = none;
5471 return;
5472 case 1:
5473 pat.field[1] = sign;
5474 pat.field[2] = space;
5475 return;
5476 case 2:
5477 pat.field[1] = space;
5478 pat.field[2] = sign;
5479 return;
5480 default:
5481 break;
5482 }
5483 break;
5484 default:
5485 break;
5486 }
5487 break;
5488 default:
5489 break;
5490 }
5491 pat.field[0] = symbol;
5492 pat.field[1] = sign;
5493 pat.field[2] = none;
5494 pat.field[3] = value;
5495}
5496
5497template<>
5498void
5499moneypunct_byname<char, false>::init(const char* nm)
5500{
5501 typedef moneypunct<char, false> base;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005502 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00005503#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005504 if (loc == 0)
5505 throw runtime_error("moneypunct_byname"
5506 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00005507#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005508#ifdef _LIBCPP_STABLE_APPLE_ABI
5509 lconv* lc = localeconv_l(loc.get());
5510#else
5511 lconv* lc = __localeconv_l(loc.get());
5512#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005513 if (*lc->mon_decimal_point)
5514 __decimal_point_ = *lc->mon_decimal_point;
5515 else
5516 __decimal_point_ = base::do_decimal_point();
5517 if (*lc->mon_thousands_sep)
5518 __thousands_sep_ = *lc->mon_thousands_sep;
5519 else
5520 __thousands_sep_ = base::do_thousands_sep();
5521 __grouping_ = lc->mon_grouping;
5522 __curr_symbol_ = lc->currency_symbol;
5523 if (lc->frac_digits != CHAR_MAX)
5524 __frac_digits_ = lc->frac_digits;
5525 else
5526 __frac_digits_ = base::do_frac_digits();
5527 if (lc->p_sign_posn == 0)
5528 __positive_sign_ = "()";
5529 else
5530 __positive_sign_ = lc->positive_sign;
5531 if (lc->n_sign_posn == 0)
5532 __negative_sign_ = "()";
5533 else
5534 __negative_sign_ = lc->negative_sign;
5535 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5536 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5537}
5538
5539template<>
5540void
5541moneypunct_byname<char, true>::init(const char* nm)
5542{
5543 typedef moneypunct<char, true> base;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005544 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00005545#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005546 if (loc == 0)
5547 throw runtime_error("moneypunct_byname"
5548 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00005549#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005550#ifdef _LIBCPP_STABLE_APPLE_ABI
5551 lconv* lc = localeconv_l(loc.get());
5552#else
5553 lconv* lc = __localeconv_l(loc.get());
5554#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005555 if (*lc->mon_decimal_point)
5556 __decimal_point_ = *lc->mon_decimal_point;
5557 else
5558 __decimal_point_ = base::do_decimal_point();
5559 if (*lc->mon_thousands_sep)
5560 __thousands_sep_ = *lc->mon_thousands_sep;
5561 else
5562 __thousands_sep_ = base::do_thousands_sep();
5563 __grouping_ = lc->mon_grouping;
5564 __curr_symbol_ = lc->int_curr_symbol;
5565 if (lc->int_frac_digits != CHAR_MAX)
5566 __frac_digits_ = lc->int_frac_digits;
5567 else
5568 __frac_digits_ = base::do_frac_digits();
5569 if (lc->int_p_sign_posn == 0)
5570 __positive_sign_ = "()";
5571 else
5572 __positive_sign_ = lc->positive_sign;
5573 if (lc->int_n_sign_posn == 0)
5574 __negative_sign_ = "()";
5575 else
5576 __negative_sign_ = lc->negative_sign;
5577 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5578 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5579}
5580
5581template<>
5582void
5583moneypunct_byname<wchar_t, false>::init(const char* nm)
5584{
5585 typedef moneypunct<wchar_t, false> base;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005586 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00005587#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005588 if (loc == 0)
5589 throw runtime_error("moneypunct_byname"
5590 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00005591#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005592#ifdef _LIBCPP_STABLE_APPLE_ABI
5593 lconv* lc = localeconv_l(loc.get());
5594#else
5595 lconv* lc = __localeconv_l(loc.get());
5596#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005597 if (*lc->mon_decimal_point)
5598 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5599 else
5600 __decimal_point_ = base::do_decimal_point();
5601 if (*lc->mon_thousands_sep)
5602 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5603 else
5604 __thousands_sep_ = base::do_thousands_sep();
5605 __grouping_ = lc->mon_grouping;
5606 wchar_t wbuf[100];
5607 mbstate_t mb = {0};
5608 const char* bb = lc->currency_symbol;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005609#ifdef _LIBCPP_STABLE_APPLE_ABI
5610 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5611#else
5612 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5613#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005614 if (j == -1)
5615 __throw_runtime_error("locale not supported");
5616 wchar_t* wbe = wbuf + j;
5617 __curr_symbol_.assign(wbuf, wbe);
5618 if (lc->frac_digits != CHAR_MAX)
5619 __frac_digits_ = lc->frac_digits;
5620 else
5621 __frac_digits_ = base::do_frac_digits();
5622 if (lc->p_sign_posn == 0)
5623 __positive_sign_ = L"()";
5624 else
5625 {
5626 mb = mbstate_t();
5627 bb = lc->positive_sign;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005628#ifdef _LIBCPP_STABLE_APPLE_ABI
5629 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5630#else
5631 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5632#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005633 if (j == -1)
5634 __throw_runtime_error("locale not supported");
5635 wbe = wbuf + j;
5636 __positive_sign_.assign(wbuf, wbe);
5637 }
5638 if (lc->n_sign_posn == 0)
5639 __negative_sign_ = L"()";
5640 else
5641 {
5642 mb = mbstate_t();
5643 bb = lc->negative_sign;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005644#ifdef _LIBCPP_STABLE_APPLE_ABI
5645 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5646#else
5647 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5648#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005649 if (j == -1)
5650 __throw_runtime_error("locale not supported");
5651 wbe = wbuf + j;
5652 __negative_sign_.assign(wbuf, wbe);
5653 }
5654 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5655 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5656}
5657
5658template<>
5659void
5660moneypunct_byname<wchar_t, true>::init(const char* nm)
5661{
5662 typedef moneypunct<wchar_t, true> base;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005663 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnant72f73582010-08-11 17:04:31 +00005664#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005665 if (loc == 0)
5666 throw runtime_error("moneypunct_byname"
5667 " failed to construct for " + string(nm));
Howard Hinnantffb308e2010-08-22 00:03:27 +00005668#endif // _LIBCPP_NO_EXCEPTIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005669#ifdef _LIBCPP_STABLE_APPLE_ABI
5670 lconv* lc = localeconv_l(loc.get());
5671#else
5672 lconv* lc = __localeconv_l(loc.get());
5673#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005674 if (*lc->mon_decimal_point)
5675 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5676 else
5677 __decimal_point_ = base::do_decimal_point();
5678 if (*lc->mon_thousands_sep)
5679 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5680 else
5681 __thousands_sep_ = base::do_thousands_sep();
5682 __grouping_ = lc->mon_grouping;
5683 wchar_t wbuf[100];
5684 mbstate_t mb = {0};
5685 const char* bb = lc->int_curr_symbol;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005686#ifdef _LIBCPP_STABLE_APPLE_ABI
5687 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5688#else
5689 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5690#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005691 if (j == -1)
5692 __throw_runtime_error("locale not supported");
5693 wchar_t* wbe = wbuf + j;
5694 __curr_symbol_.assign(wbuf, wbe);
5695 if (lc->int_frac_digits != CHAR_MAX)
5696 __frac_digits_ = lc->int_frac_digits;
5697 else
5698 __frac_digits_ = base::do_frac_digits();
5699 if (lc->int_p_sign_posn == 0)
5700 __positive_sign_ = L"()";
5701 else
5702 {
5703 mb = mbstate_t();
5704 bb = lc->positive_sign;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005705#ifdef _LIBCPP_STABLE_APPLE_ABI
5706 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5707#else
5708 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5709#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005710 if (j == -1)
5711 __throw_runtime_error("locale not supported");
5712 wbe = wbuf + j;
5713 __positive_sign_.assign(wbuf, wbe);
5714 }
5715 if (lc->int_n_sign_posn == 0)
5716 __negative_sign_ = L"()";
5717 else
5718 {
5719 mb = mbstate_t();
5720 bb = lc->negative_sign;
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00005721#ifdef _LIBCPP_STABLE_APPLE_ABI
5722 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5723#else
5724 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5725#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005726 if (j == -1)
5727 __throw_runtime_error("locale not supported");
5728 wbe = wbuf + j;
5729 __negative_sign_.assign(wbuf, wbe);
5730 }
5731 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5732 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5733}
5734
5735void __do_nothing(void*) {}
5736
5737void __throw_runtime_error(const char* msg)
5738{
Howard Hinnant72f73582010-08-11 17:04:31 +00005739#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantc51e1022010-05-11 19:42:16 +00005740 throw runtime_error(msg);
Howard Hinnant72f73582010-08-11 17:04:31 +00005741#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00005742}
5743
5744template class collate<char>;
5745template class collate<wchar_t>;
5746
5747template class num_get<char>;
5748template class num_get<wchar_t>;
5749
5750template class __num_get<char>;
5751template class __num_get<wchar_t>;
5752
5753template class num_put<char>;
5754template class num_put<wchar_t>;
5755
5756template class __num_put<char>;
5757template class __num_put<wchar_t>;
5758
5759template class time_get<char>;
5760template class time_get<wchar_t>;
5761
5762template class time_get_byname<char>;
5763template class time_get_byname<wchar_t>;
5764
5765template class time_put<char>;
5766template class time_put<wchar_t>;
5767
5768template class time_put_byname<char>;
5769template class time_put_byname<wchar_t>;
5770
5771template class moneypunct<char, false>;
5772template class moneypunct<char, true>;
5773template class moneypunct<wchar_t, false>;
5774template class moneypunct<wchar_t, true>;
5775
5776template class moneypunct_byname<char, false>;
5777template class moneypunct_byname<char, true>;
5778template class moneypunct_byname<wchar_t, false>;
5779template class moneypunct_byname<wchar_t, true>;
5780
5781template class money_get<char>;
5782template class money_get<wchar_t>;
5783
5784template class __money_get<char>;
5785template class __money_get<wchar_t>;
5786
5787template class money_put<char>;
5788template class money_put<wchar_t>;
5789
5790template class __money_put<char>;
5791template class __money_put<wchar_t>;
5792
5793template class messages<char>;
5794template class messages<wchar_t>;
5795
5796template class messages_byname<char>;
5797template class messages_byname<wchar_t>;
5798
5799template class codecvt_byname<char, char, mbstate_t>;
5800template class codecvt_byname<wchar_t, char, mbstate_t>;
5801template class codecvt_byname<char16_t, char, mbstate_t>;
5802template class codecvt_byname<char32_t, char, mbstate_t>;
5803
5804template class __vector_base_common<true>;
5805
5806_LIBCPP_END_NAMESPACE_STD