blob: 5d1d607ff6b1cc36122a3a465abf2cddee10a9a0 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001//===------------------------- locale.cpp ---------------------------------===//
2//
Howard Hinnantf5256e12010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "string"
11#include "locale"
Howard Hinnant87d1a8a2010-05-30 21:39:41 +000012#include "codecvt"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000013#include "vector"
14#include "algorithm"
15#include "algorithm"
16#include "typeinfo"
Howard Hinnantd318d492011-06-30 14:21:55 +000017#include "type_traits"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000018#include "clocale"
19#include "cstring"
20#include "cwctype"
21#include "__sso_allocator"
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000022#include <langinfo.h>
23#include <stdlib.h>
24
Howard Hinnantd318d492011-06-30 14:21:55 +000025namespace {
26 typedef std::remove_pointer<locale_t>::type locale_struct;
27 typedef std::unique_ptr<locale_struct, decltype(&freelocale)> locale_unique_ptr;
28 typedef std::unique_ptr<locale_struct, decltype(&uselocale)> locale_raii;
29}
30
31namespace with_locale { namespace {
32#ifdef __APPLE__
33 using ::btowc_l;
34 using ::wctob_l;
35 using ::wcsnrtombs_l;
36 using ::wcrtomb_l;
37 using ::mbsnrtowcs_l;
38 using ::mbrtowc_l;
39 using ::mbtowc_l;
40 using ::mbrlen_l;
41 using ::localeconv_l;
42 using ::mbsrtowcs_l;
43
Howard Hinnant0949eed2011-06-30 21:18:19 +000044 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
Howard Hinnantd318d492011-06-30 14:21:55 +000045 inline _LIBCPP_INLINE_VISIBILITY
46 mb_cur_max_l(locale_t loc)
47 {
48 return MB_CUR_MAX_L(loc);
49 }
50#else
51 template
52 <typename Function, typename ...Args>
53 auto using_locale(Function f, locale_t loc, Args&&... params) -> decltype(f(std::forward<Args>(params)...))
54 {
55 locale_raii current(uselocale(loc), uselocale);
56 return f(std::forward<Args>(params)...);
57 }
58
59 decltype(MB_CUR_MAX)
60 mb_cur_max_l(locale_t loc)
61 {
62 locale_raii current(uselocale(loc), uselocale);
63 return MB_CUR_MAX;
64 }
65
66 wint_t btowc_l(int c, locale_t l) { return using_locale(&btowc, l, c); }
67 int wctob_l(wint_t c, locale_t l) { return using_locale(&wctob, l, c); }
68 size_t wcsnrtombs_l(char * dest,
69 const wchar_t * * src,
70 size_t nwc,
71 size_t len,
72 mbstate_t * ps,
73 locale_t l)
74 {
75 return using_locale(&wcsnrtombs, l, dest, src, nwc, len, ps);
76 }
77 size_t wcrtomb_l(char *s, wchar_t wc, mbstate_t *ps, locale_t l)
78 {
79 return using_locale(&wcrtomb, l, s, wc, ps);
80 }
81 size_t mbsnrtowcs_l(wchar_t * dest,
82 const char * * src,
83 size_t nms,
84 size_t len,
85 mbstate_t * ps,
86 locale_t l)
87 {
88 return using_locale(&mbsnrtowcs, l, dest, src, nms, len, ps);
89 }
90 size_t mbrtowc_l(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps, locale_t l)
91 {
92 return using_locale(&mbrtowc, l, pwc, s, n, ps);
93 }
94 int mbtowc_l(wchar_t * pwc, const char * pmb, size_t max, locale_t l)
95 {
96 return using_locale(&mbtowc, l, pwc, pmb, max);
97 }
98 size_t mbrlen_l(const char *s, size_t n, mbstate_t *ps, locale_t l)
99 {
100 return using_locale(&mbrlen, l, s, n, ps);
101 }
102 struct lconv *localeconv_l(locale_t l)
103 {
104 return using_locale(&localeconv, l);
105 }
106 size_t mbsrtowcs_l(wchar_t * dest,
107 const char * * src,
108 size_t len,
109 mbstate_t * ps,
110 locale_t l)
111 {
112 return using_locale(&mbsrtowcs, l, dest, src, len, ps);
113 }
114#endif
115} }
116
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000117_LIBCPP_BEGIN_NAMESPACE_STD
118
119namespace {
120
121struct release
122{
123 void operator()(locale::facet* p) {p->__release_shared();}
124};
125
126template <class T, class A0>
127inline
128T&
129make(A0 a0)
130{
131 static typename aligned_storage<sizeof(T)>::type buf;
132 ::new (&buf) T(a0);
133 return *(T*)&buf;
134}
135
136template <class T, class A0, class A1>
137inline
138T&
139make(A0 a0, A1 a1)
140{
141 static typename aligned_storage<sizeof(T)>::type buf;
142 ::new (&buf) T(a0, a1);
143 return *(T*)&buf;
144}
145
146template <class T, class A0, class A1, class A2>
147inline
148T&
149make(A0 a0, A1 a1, A2 a2)
150{
151 static typename aligned_storage<sizeof(T)>::type buf;
152 ::new (&buf) T(a0, a1, a2);
153 return *(T*)&buf;
154}
155
156}
157
158class _LIBCPP_HIDDEN locale::__imp
159 : public facet
160{
161 enum {N = 28};
162 string name_;
163 vector<facet*, __sso_allocator<facet*, N> > facets_;
164public:
165 explicit __imp(size_t refs = 0);
166 explicit __imp(const string& name, size_t refs = 0);
167 __imp(const __imp&);
168 __imp(const __imp&, const string&, locale::category c);
169 __imp(const __imp& other, const __imp& one, locale::category c);
170 __imp(const __imp&, facet* f, long id);
171 ~__imp();
172
173 const string& name() const {return name_;}
174 bool has_facet(long id) const {return id < facets_.size() && facets_[id];}
175 const locale::facet* use_facet(long id) const;
176
177 static const locale& make_classic();
178 static locale& make_global();
179private:
180 void install(facet* f, long id);
181 template <class F> void install(F* f) {install(f, f->id.__get());}
182 template <class F> void install_from(const __imp& other);
183};
184
185locale::__imp::__imp(size_t refs)
186 : facet(refs),
187 name_("C"),
188 facets_(N)
189{
190 facets_.clear();
Howard Hinnant0949eed2011-06-30 21:18:19 +0000191 install(&make<_VSTD::collate<char> >(1));
192 install(&make<_VSTD::collate<wchar_t> >(1));
193 install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1));
194 install(&make<_VSTD::ctype<wchar_t> >(1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195 install(&make<codecvt<char, char, mbstate_t> >(1));
196 install(&make<codecvt<wchar_t, char, mbstate_t> >(1));
197 install(&make<codecvt<char16_t, char, mbstate_t> >(1));
198 install(&make<codecvt<char32_t, char, mbstate_t> >(1));
199 install(&make<numpunct<char> >(1));
200 install(&make<numpunct<wchar_t> >(1));
201 install(&make<num_get<char> >(1));
202 install(&make<num_get<wchar_t> >(1));
203 install(&make<num_put<char> >(1));
204 install(&make<num_put<wchar_t> >(1));
205 install(&make<moneypunct<char, false> >(1));
206 install(&make<moneypunct<char, true> >(1));
207 install(&make<moneypunct<wchar_t, false> >(1));
208 install(&make<moneypunct<wchar_t, true> >(1));
209 install(&make<money_get<char> >(1));
210 install(&make<money_get<wchar_t> >(1));
211 install(&make<money_put<char> >(1));
212 install(&make<money_put<wchar_t> >(1));
213 install(&make<time_get<char> >(1));
214 install(&make<time_get<wchar_t> >(1));
215 install(&make<time_put<char> >(1));
216 install(&make<time_put<wchar_t> >(1));
Howard Hinnant0949eed2011-06-30 21:18:19 +0000217 install(&make<_VSTD::messages<char> >(1));
218 install(&make<_VSTD::messages<wchar_t> >(1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000219}
220
221locale::__imp::__imp(const string& name, size_t refs)
222 : facet(refs),
223 name_(name),
224 facets_(N)
225{
Howard Hinnantd4444702010-08-11 17:04:31 +0000226#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000227 try
228 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000229#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000230 facets_ = locale::classic().__locale_->facets_;
231 for (unsigned i = 0; i < facets_.size(); ++i)
232 if (facets_[i])
233 facets_[i]->__add_shared();
234 install(new collate_byname<char>(name_));
235 install(new collate_byname<wchar_t>(name_));
236 install(new ctype_byname<char>(name_));
237 install(new ctype_byname<wchar_t>(name_));
238 install(new codecvt_byname<char, char, mbstate_t>(name_));
239 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
240 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
241 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
242 install(new numpunct_byname<char>(name_));
243 install(new numpunct_byname<wchar_t>(name_));
244 install(new moneypunct_byname<char, false>(name_));
245 install(new moneypunct_byname<char, true>(name_));
246 install(new moneypunct_byname<wchar_t, false>(name_));
247 install(new moneypunct_byname<wchar_t, true>(name_));
248 install(new time_get_byname<char>(name_));
249 install(new time_get_byname<wchar_t>(name_));
250 install(new time_put_byname<char>(name_));
251 install(new time_put_byname<wchar_t>(name_));
252 install(new messages_byname<char>(name_));
253 install(new messages_byname<wchar_t>(name_));
Howard Hinnantd4444702010-08-11 17:04:31 +0000254#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000255 }
256 catch (...)
257 {
258 for (unsigned i = 0; i < facets_.size(); ++i)
259 if (facets_[i])
260 facets_[i]->__release_shared();
261 throw;
262 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000263#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000264}
265
266locale::__imp::__imp(const __imp& other)
267 : name_(other.name_),
268 facets_(max<size_t>(N, other.facets_.size()))
269{
270 facets_ = other.facets_;
271 for (unsigned i = 0; i < facets_.size(); ++i)
272 if (facets_[i])
273 facets_[i]->__add_shared();
274}
275
276locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
277 : name_("*"),
278 facets_(N)
279{
280 facets_ = other.facets_;
281 for (unsigned i = 0; i < facets_.size(); ++i)
282 if (facets_[i])
283 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000284#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000285 try
286 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000287#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288 if (c & locale::collate)
289 {
290 install(new collate_byname<char>(name));
291 install(new collate_byname<wchar_t>(name));
292 }
293 if (c & locale::ctype)
294 {
295 install(new ctype_byname<char>(name));
296 install(new ctype_byname<wchar_t>(name));
297 install(new codecvt_byname<char, char, mbstate_t>(name));
298 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
299 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
300 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
301 }
302 if (c & locale::monetary)
303 {
304 install(new moneypunct_byname<char, false>(name));
305 install(new moneypunct_byname<char, true>(name));
306 install(new moneypunct_byname<wchar_t, false>(name));
307 install(new moneypunct_byname<wchar_t, true>(name));
308 }
309 if (c & locale::numeric)
310 {
311 install(new numpunct_byname<char>(name));
312 install(new numpunct_byname<wchar_t>(name));
313 }
314 if (c & locale::time)
315 {
316 install(new time_get_byname<char>(name));
317 install(new time_get_byname<wchar_t>(name));
318 install(new time_put_byname<char>(name));
319 install(new time_put_byname<wchar_t>(name));
320 }
321 if (c & locale::messages)
322 {
323 install(new messages_byname<char>(name));
324 install(new messages_byname<wchar_t>(name));
325 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000326#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000327 }
328 catch (...)
329 {
330 for (unsigned i = 0; i < facets_.size(); ++i)
331 if (facets_[i])
332 facets_[i]->__release_shared();
333 throw;
334 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000335#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000336}
337
338template<class F>
339inline
340void
341locale::__imp::install_from(const locale::__imp& one)
342{
343 long id = F::id.__get();
344 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
345}
346
347locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
348 : name_("*"),
349 facets_(N)
350{
351 facets_ = other.facets_;
352 for (unsigned i = 0; i < facets_.size(); ++i)
353 if (facets_[i])
354 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000355#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000356 try
357 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000358#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000359 if (c & locale::collate)
360 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000361 install_from<_VSTD::collate<char> >(one);
362 install_from<_VSTD::collate<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000363 }
364 if (c & locale::ctype)
365 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000366 install_from<_VSTD::ctype<char> >(one);
367 install_from<_VSTD::ctype<wchar_t> >(one);
368 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
369 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
370 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
371 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372 }
373 if (c & locale::monetary)
374 {
375 install_from<moneypunct<char, false> >(one);
376 install_from<moneypunct<char, true> >(one);
377 install_from<moneypunct<wchar_t, false> >(one);
378 install_from<moneypunct<wchar_t, true> >(one);
379 install_from<money_get<char> >(one);
380 install_from<money_get<wchar_t> >(one);
381 install_from<money_put<char> >(one);
382 install_from<money_put<wchar_t> >(one);
383 }
384 if (c & locale::numeric)
385 {
386 install_from<numpunct<char> >(one);
387 install_from<numpunct<wchar_t> >(one);
388 install_from<num_get<char> >(one);
389 install_from<num_get<wchar_t> >(one);
390 install_from<num_put<char> >(one);
391 install_from<num_put<wchar_t> >(one);
392 }
393 if (c & locale::time)
394 {
395 install_from<time_get<char> >(one);
396 install_from<time_get<wchar_t> >(one);
397 install_from<time_put<char> >(one);
398 install_from<time_put<wchar_t> >(one);
399 }
400 if (c & locale::messages)
401 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000402 install_from<_VSTD::messages<char> >(one);
403 install_from<_VSTD::messages<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000405#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000406 }
407 catch (...)
408 {
409 for (unsigned i = 0; i < facets_.size(); ++i)
410 if (facets_[i])
411 facets_[i]->__release_shared();
412 throw;
413 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000414#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000415}
416
417locale::__imp::__imp(const __imp& other, facet* f, long id)
418 : name_("*"),
419 facets_(max<size_t>(N, other.facets_.size()+1))
420{
421 f->__add_shared();
422 unique_ptr<facet, release> hold(f);
423 facets_ = other.facets_;
424 for (unsigned i = 0; i < other.facets_.size(); ++i)
425 if (facets_[i])
426 facets_[i]->__add_shared();
427 install(hold.get(), id);
428}
429
430locale::__imp::~__imp()
431{
432 for (unsigned i = 0; i < facets_.size(); ++i)
433 if (facets_[i])
434 facets_[i]->__release_shared();
435}
436
437void
438locale::__imp::install(facet* f, long id)
439{
440 f->__add_shared();
441 unique_ptr<facet, release> hold(f);
442 if (id >= facets_.size())
443 facets_.resize(id+1);
444 if (facets_[id])
445 facets_[id]->__release_shared();
446 facets_[id] = hold.release();
447}
448
449const locale::facet*
450locale::__imp::use_facet(long id) const
451{
Howard Hinnantd4444702010-08-11 17:04:31 +0000452#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000453 if (!has_facet(id))
454 throw bad_cast();
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000455#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000456 return facets_[id];
457}
458
459// locale
460
461const locale&
462locale::__imp::make_classic()
463{
464 // only one thread can get in here and it only gets in once
465 static aligned_storage<sizeof(locale)>::type buf;
466 locale* c = (locale*)&buf;
467 c->__locale_ = &make<__imp>(1);
468 return *c;
469}
470
471const locale&
472locale::classic()
473{
474 static const locale& c = __imp::make_classic();
475 return c;
476}
477
478locale&
479locale::__imp::make_global()
480{
481 // only one thread can get in here and it only gets in once
482 static aligned_storage<sizeof(locale)>::type buf;
483 locale* g = (locale*)&buf;
484 ::new (&buf) locale(locale::classic());
485 return *(locale*)&buf;
486}
487
488locale&
489locale::__global()
490{
491 static locale& g = __imp::make_global();
492 return g;
493}
494
Howard Hinnantc9834542011-05-31 15:34:58 +0000495locale::locale() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000496 : __locale_(__global().__locale_)
497{
498 __locale_->__add_shared();
499}
500
Howard Hinnantc9834542011-05-31 15:34:58 +0000501locale::locale(const locale& l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000502 : __locale_(l.__locale_)
503{
504 __locale_->__add_shared();
505}
506
Howard Hinnantc9834542011-05-31 15:34:58 +0000507locale::~locale()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000508{
509 __locale_->__release_shared();
510}
511
512const locale&
Howard Hinnantc9834542011-05-31 15:34:58 +0000513locale::operator=(const locale& other) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000514{
515 other.__locale_->__add_shared();
516 __locale_->__release_shared();
517 __locale_ = other.__locale_;
518 return *this;
519}
520
521locale::locale(const char* name)
Howard Hinnantd4444702010-08-11 17:04:31 +0000522#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000523 : __locale_(name ? new __imp(name)
524 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000525#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000526 : __locale_(new __imp(name))
527#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000528{
529 __locale_->__add_shared();
530}
531
532locale::locale(const string& name)
533 : __locale_(new __imp(name))
534{
535 __locale_->__add_shared();
536}
537
538locale::locale(const locale& other, const char* name, category c)
Howard Hinnantd4444702010-08-11 17:04:31 +0000539#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000540 : __locale_(name ? new __imp(*other.__locale_, name, c)
541 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000542#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000543 : __locale_(new __imp(*other.__locale_, name, c))
544#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000545{
546 __locale_->__add_shared();
547}
548
549locale::locale(const locale& other, const string& name, category c)
550 : __locale_(new __imp(*other.__locale_, name, c))
551{
552 __locale_->__add_shared();
553}
554
555locale::locale(const locale& other, const locale& one, category c)
556 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
557{
558 __locale_->__add_shared();
559}
560
561string
562locale::name() const
563{
564 return __locale_->name();
565}
566
567void
568locale::__install_ctor(const locale& other, facet* f, long id)
569{
570 if (f)
571 __locale_ = new __imp(*other.__locale_, f, id);
572 else
573 __locale_ = other.__locale_;
574 __locale_->__add_shared();
575}
576
577locale
578locale::global(const locale& loc)
579{
580 locale& g = __global();
581 locale r = g;
582 g = loc;
583 if (g.name() != "*")
584 setlocale(LC_ALL, g.name().c_str());
585 return r;
586}
587
588bool
589locale::has_facet(id& x) const
590{
591 return __locale_->has_facet(x.__get());
592}
593
594const locale::facet*
595locale::use_facet(id& x) const
596{
597 return __locale_->use_facet(x.__get());
598}
599
600bool
601locale::operator==(const locale& y) const
602{
603 return (__locale_ == y.__locale_)
604 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
605}
606
607// locale::facet
608
609locale::facet::~facet()
610{
611}
612
613void
Howard Hinnant1694d232011-05-28 14:41:13 +0000614locale::facet::__on_zero_shared() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000615{
616 delete this;
617}
618
619// locale::id
620
621int32_t locale::id::__next_id = 0;
622
623namespace
624{
625
626class __fake_bind
627{
628 locale::id* id_;
629 void (locale::id::* pmf_)();
630public:
631 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
632 : id_(id), pmf_(pmf) {}
633
634 void operator()() const
635 {
636 (id_->*pmf_)();
637 }
638};
639
640}
641
642long
643locale::id::__get()
644{
645 call_once(__flag_, __fake_bind(&locale::id::__init, this));
646 return __id_ - 1;
647}
648
649void
650locale::id::__init()
651{
Howard Hinnantadff4892010-05-24 17:49:41 +0000652 __id_ = __sync_add_and_fetch(&__next_id, 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000653}
654
655// template <> class collate_byname<char>
656
657collate_byname<char>::collate_byname(const char* n, size_t refs)
658 : collate<char>(refs),
659 __l(newlocale(LC_ALL_MASK, n, 0))
660{
Howard Hinnantd4444702010-08-11 17:04:31 +0000661#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000662 if (__l == 0)
663 throw runtime_error("collate_byname<char>::collate_byname"
664 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000665#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000666}
667
668collate_byname<char>::collate_byname(const string& name, size_t refs)
669 : collate<char>(refs),
670 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
671{
Howard Hinnantd4444702010-08-11 17:04:31 +0000672#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000673 if (__l == 0)
674 throw runtime_error("collate_byname<char>::collate_byname"
675 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000676#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000677}
678
679collate_byname<char>::~collate_byname()
680{
681 freelocale(__l);
682}
683
684int
685collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
686 const char_type* __lo2, const char_type* __hi2) const
687{
688 string_type lhs(__lo1, __hi1);
689 string_type rhs(__lo2, __hi2);
690 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
691 if (r < 0)
692 return -1;
693 if (r > 0)
694 return 1;
695 return r;
696}
697
698collate_byname<char>::string_type
699collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
700{
701 const string_type in(lo, hi);
702 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
703 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
704 return out;
705}
706
707// template <> class collate_byname<wchar_t>
708
709collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
710 : collate<wchar_t>(refs),
711 __l(newlocale(LC_ALL_MASK, n, 0))
712{
Howard Hinnantd4444702010-08-11 17:04:31 +0000713#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714 if (__l == 0)
715 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
716 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000717#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000718}
719
720collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
721 : collate<wchar_t>(refs),
722 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
723{
Howard Hinnantd4444702010-08-11 17:04:31 +0000724#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000725 if (__l == 0)
726 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
727 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000728#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000729}
730
731collate_byname<wchar_t>::~collate_byname()
732{
733 freelocale(__l);
734}
735
736int
737collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
738 const char_type* __lo2, const char_type* __hi2) const
739{
740 string_type lhs(__lo1, __hi1);
741 string_type rhs(__lo2, __hi2);
742 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
743 if (r < 0)
744 return -1;
745 if (r > 0)
746 return 1;
747 return r;
748}
749
750collate_byname<wchar_t>::string_type
751collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
752{
753 const string_type in(lo, hi);
754 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
755 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
756 return out;
757}
758
759// template <> class ctype<wchar_t>;
760
761locale::id ctype<wchar_t>::id;
762
763ctype<wchar_t>::~ctype()
764{
765}
766
767bool
768ctype<wchar_t>::do_is(mask m, char_type c) const
769{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000770#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000771 return isascii(c) ? _DefaultRuneLocale.__runetype[c] & m : false;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000772#else
773 return false;
774#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000775}
776
777const wchar_t*
778ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
779{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000780#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000781 for (; low != high; ++low, ++vec)
782 *vec = static_cast<mask>(isascii(*low) ? _DefaultRuneLocale.__runetype[*low] : 0);
783 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000784#else
785 return NULL;
786#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000787}
788
789const wchar_t*
790ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
791{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000792#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000793 for (; low != high; ++low)
794 if (isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m))
795 break;
796 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000797#else
798 return NULL;
799#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000800}
801
802const wchar_t*
803ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
804{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000805#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000806 for (; low != high; ++low)
807 if (!(isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m)))
808 break;
809 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000810#else
811 return NULL;
812#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000813}
814
815wchar_t
816ctype<wchar_t>::do_toupper(char_type c) const
817{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000818#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000819 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000820#else
821 return 0;
822#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000823}
824
825const wchar_t*
826ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
827{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000828#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000829 for (; low != high; ++low)
830 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
831 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000832#else
833 return NULL;
834#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000835}
836
837wchar_t
838ctype<wchar_t>::do_tolower(char_type c) const
839{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000840#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000841 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000842#else
843 return 0;
844#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000845}
846
847const wchar_t*
848ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
849{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000850#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000851 for (; low != high; ++low)
852 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
853 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000854#else
855 return NULL;
856#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000857}
858
859wchar_t
860ctype<wchar_t>::do_widen(char c) const
861{
862 return c;
863}
864
865const char*
866ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
867{
868 for (; low != high; ++low, ++dest)
869 *dest = *low;
870 return low;
871}
872
873char
874ctype<wchar_t>::do_narrow(char_type c, char dfault) const
875{
876 if (isascii(c))
877 return static_cast<char>(c);
878 return dfault;
879}
880
881const wchar_t*
882ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
883{
884 for (; low != high; ++low, ++dest)
885 if (isascii(*low))
886 *dest = *low;
887 else
888 *dest = dfault;
889 return low;
890}
891
892// template <> class ctype<char>;
893
894locale::id ctype<char>::id;
895
896ctype<char>::ctype(const mask* tab, bool del, size_t refs)
897 : locale::facet(refs),
898 __tab_(tab),
899 __del_(del)
900{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000901#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000902 if (__tab_ == 0)
903 __tab_ = _DefaultRuneLocale.__runetype;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000904#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000905}
906
907ctype<char>::~ctype()
908{
909 if (__tab_ && __del_)
910 delete [] __tab_;
911}
912
913char
914ctype<char>::do_toupper(char_type c) const
915{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000916#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000917 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000918#else
919 return 0;
920#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000921}
922
923const char*
924ctype<char>::do_toupper(char_type* low, const char_type* high) const
925{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000926#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 for (; low != high; ++low)
928 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
929 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000930#else
931 return NULL;
932#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933}
934
935char
936ctype<char>::do_tolower(char_type c) const
937{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000938#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000939 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000940#else
941 return 0;
942#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000943}
944
945const char*
946ctype<char>::do_tolower(char_type* low, const char_type* high) const
947{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000948#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000949 for (; low != high; ++low)
950 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
951 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000952#else
953 return NULL;
954#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000955}
956
957char
958ctype<char>::do_widen(char c) const
959{
960 return c;
961}
962
963const char*
964ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
965{
966 for (; low != high; ++low, ++dest)
967 *dest = *low;
968 return low;
969}
970
971char
972ctype<char>::do_narrow(char_type c, char dfault) const
973{
974 if (isascii(c))
975 return static_cast<char>(c);
976 return dfault;
977}
978
979const char*
980ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
981{
982 for (; low != high; ++low, ++dest)
983 if (isascii(*low))
984 *dest = *low;
985 else
986 *dest = dfault;
987 return low;
988}
989
990const ctype<char>::mask*
Howard Hinnantc9834542011-05-31 15:34:58 +0000991ctype<char>::classic_table() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000992{
Michael J. Spencer626916f2010-12-10 19:47:54 +0000993#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000994 return _DefaultRuneLocale.__runetype;
Michael J. Spencer626916f2010-12-10 19:47:54 +0000995#else
996 return NULL;
997#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000998}
999
1000// template <> class ctype_byname<char>
1001
1002ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1003 : ctype<char>(0, false, refs),
1004 __l(newlocale(LC_ALL_MASK, name, 0))
1005{
Howard Hinnantd4444702010-08-11 17:04:31 +00001006#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001007 if (__l == 0)
1008 throw runtime_error("ctype_byname<char>::ctype_byname"
1009 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001010#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001011}
1012
1013ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1014 : ctype<char>(0, false, refs),
1015 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1016{
Howard Hinnantd4444702010-08-11 17:04:31 +00001017#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001018 if (__l == 0)
1019 throw runtime_error("ctype_byname<char>::ctype_byname"
1020 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001021#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001022}
1023
1024ctype_byname<char>::~ctype_byname()
1025{
1026 freelocale(__l);
1027}
1028
1029char
1030ctype_byname<char>::do_toupper(char_type c) const
1031{
1032 return toupper_l(c, __l);
1033}
1034
1035const char*
1036ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1037{
1038 for (; low != high; ++low)
1039 *low = toupper_l(*low, __l);
1040 return low;
1041}
1042
1043char
1044ctype_byname<char>::do_tolower(char_type c) const
1045{
1046 return tolower_l(c, __l);
1047}
1048
1049const char*
1050ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1051{
1052 for (; low != high; ++low)
1053 *low = tolower_l(*low, __l);
1054 return low;
1055}
1056
1057// template <> class ctype_byname<wchar_t>
1058
1059ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1060 : ctype<wchar_t>(refs),
1061 __l(newlocale(LC_ALL_MASK, name, 0))
1062{
Howard Hinnantd4444702010-08-11 17:04:31 +00001063#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001064 if (__l == 0)
1065 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1066 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001067#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001068}
1069
1070ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1071 : ctype<wchar_t>(refs),
1072 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1073{
Howard Hinnantd4444702010-08-11 17:04:31 +00001074#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001075 if (__l == 0)
1076 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1077 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001078#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001079}
1080
1081ctype_byname<wchar_t>::~ctype_byname()
1082{
1083 freelocale(__l);
1084}
1085
1086bool
1087ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1088{
1089 return static_cast<bool>(iswctype_l(c, m, __l));
1090}
1091
1092const wchar_t*
1093ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1094{
Michael J. Spencer626916f2010-12-10 19:47:54 +00001095#ifdef __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001096 for (; low != high; ++low, ++vec)
1097 {
1098 if (isascii(*low))
1099 *vec = static_cast<mask>(_DefaultRuneLocale.__runetype[*low]);
1100 else
1101 {
1102 *vec = 0;
1103 if (iswspace_l(*low, __l))
1104 *vec |= space;
1105 if (iswprint_l(*low, __l))
1106 *vec |= print;
1107 if (iswcntrl_l(*low, __l))
1108 *vec |= cntrl;
1109 if (iswupper_l(*low, __l))
1110 *vec |= upper;
1111 if (iswlower_l(*low, __l))
1112 *vec |= lower;
1113 if (iswalpha_l(*low, __l))
1114 *vec |= alpha;
1115 if (iswdigit_l(*low, __l))
1116 *vec |= digit;
1117 if (iswpunct_l(*low, __l))
1118 *vec |= punct;
1119 if (iswxdigit_l(*low, __l))
1120 *vec |= xdigit;
1121 }
1122 }
1123 return low;
Michael J. Spencer626916f2010-12-10 19:47:54 +00001124#else
1125 return NULL;
1126#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001127}
1128
1129const wchar_t*
1130ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1131{
1132 for (; low != high; ++low)
1133 if (iswctype_l(*low, m, __l))
1134 break;
1135 return low;
1136}
1137
1138const wchar_t*
1139ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1140{
1141 for (; low != high; ++low)
1142 if (!iswctype_l(*low, m, __l))
1143 break;
1144 return low;
1145}
1146
1147wchar_t
1148ctype_byname<wchar_t>::do_toupper(char_type c) const
1149{
1150 return towupper_l(c, __l);
1151}
1152
1153const wchar_t*
1154ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1155{
1156 for (; low != high; ++low)
1157 *low = towupper_l(*low, __l);
1158 return low;
1159}
1160
1161wchar_t
1162ctype_byname<wchar_t>::do_tolower(char_type c) const
1163{
1164 return towlower_l(c, __l);
1165}
1166
1167const wchar_t*
1168ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1169{
1170 for (; low != high; ++low)
1171 *low = towlower_l(*low, __l);
1172 return low;
1173}
1174
1175wchar_t
1176ctype_byname<wchar_t>::do_widen(char c) const
1177{
Howard Hinnantd318d492011-06-30 14:21:55 +00001178 return with_locale::btowc_l(c, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001179}
1180
1181const char*
1182ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1183{
1184 for (; low != high; ++low, ++dest)
Howard Hinnantd318d492011-06-30 14:21:55 +00001185 *dest = with_locale::btowc_l(*low, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001186 return low;
1187}
1188
1189char
1190ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1191{
Howard Hinnantd318d492011-06-30 14:21:55 +00001192 int r = with_locale::wctob_l(c, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001193 return r != WEOF ? static_cast<char>(r) : dfault;
1194}
1195
1196const wchar_t*
1197ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1198{
1199 for (; low != high; ++low, ++dest)
1200 {
Howard Hinnantd318d492011-06-30 14:21:55 +00001201 int r = with_locale::wctob_l(*low, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001202 *dest = r != WEOF ? static_cast<char>(r) : dfault;
1203 }
1204 return low;
1205}
1206
1207// template <> class codecvt<char, char, mbstate_t>
1208
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001209locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001210
1211codecvt<char, char, mbstate_t>::~codecvt()
1212{
1213}
1214
1215codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001216codecvt<char, char, mbstate_t>::do_out(state_type&,
1217 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001218 extern_type* to, extern_type*, extern_type*& to_nxt) const
1219{
1220 frm_nxt = frm;
1221 to_nxt = to;
1222 return noconv;
1223}
1224
1225codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001226codecvt<char, char, mbstate_t>::do_in(state_type&,
1227 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001228 intern_type* to, intern_type*, intern_type*& to_nxt) const
1229{
1230 frm_nxt = frm;
1231 to_nxt = to;
1232 return noconv;
1233}
1234
1235codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001236codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001237 extern_type* to, extern_type*, extern_type*& to_nxt) const
1238{
1239 to_nxt = to;
1240 return noconv;
1241}
1242
1243int
Howard Hinnantc9834542011-05-31 15:34:58 +00001244codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001245{
1246 return 1;
1247}
1248
1249bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001250codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001251{
1252 return true;
1253}
1254
1255int
1256codecvt<char, char, mbstate_t>::do_length(state_type&,
1257 const extern_type* frm, const extern_type* end, size_t mx) const
1258{
1259 return static_cast<int>(min<size_t>(mx, end-frm));
1260}
1261
1262int
Howard Hinnantc9834542011-05-31 15:34:58 +00001263codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001264{
1265 return 1;
1266}
1267
1268// template <> class codecvt<wchar_t, char, mbstate_t>
1269
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001270locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001271
1272codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1273 : locale::facet(refs),
1274 __l(0)
1275{
1276}
1277
1278codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1279 : locale::facet(refs),
1280 __l(newlocale(LC_ALL_MASK, nm, 0))
1281{
Howard Hinnantd4444702010-08-11 17:04:31 +00001282#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001283 if (__l == 0)
1284 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1285 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001286#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001287}
1288
1289codecvt<wchar_t, char, mbstate_t>::~codecvt()
1290{
1291 if (__l != 0)
1292 freelocale(__l);
1293}
1294
1295codecvt<wchar_t, char, mbstate_t>::result
1296codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001297 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001298 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1299{
1300 // look for first internal null in frm
1301 const intern_type* fend = frm;
1302 for (; fend != frm_end; ++fend)
1303 if (*fend == 0)
1304 break;
1305 // loop over all null-terminated sequences in frm
1306 to_nxt = to;
1307 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1308 {
1309 // save state in case needed to reover to_nxt on error
1310 mbstate_t save_state = st;
Howard Hinnantd318d492011-06-30 14:21:55 +00001311 size_t n = with_locale::wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001312 if (n == size_t(-1))
1313 {
1314 // need to recover to_nxt
1315 for (to_nxt = to; frm != frm_nxt; ++frm)
1316 {
Howard Hinnantd318d492011-06-30 14:21:55 +00001317 n = with_locale::wcrtomb_l(to_nxt, *frm, &save_state, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001318 if (n == size_t(-1))
1319 break;
1320 to_nxt += n;
1321 }
1322 frm_nxt = frm;
1323 return error;
1324 }
1325 if (n == 0)
1326 return partial;
1327 to_nxt += n;
1328 if (to_nxt == to_end)
1329 break;
1330 if (fend != frm_end) // set up next null terminated sequence
1331 {
1332 // Try to write the terminating null
1333 extern_type tmp[MB_LEN_MAX];
Howard Hinnantd318d492011-06-30 14:21:55 +00001334 n = with_locale::wcrtomb_l(tmp, intern_type(), &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001335 if (n == size_t(-1)) // on error
1336 return error;
1337 if (n > to_end-to_nxt) // is there room?
1338 return partial;
1339 for (extern_type* p = tmp; n; --n) // write it
1340 *to_nxt++ = *p++;
1341 ++frm_nxt;
1342 // look for next null in frm
1343 for (fend = frm_nxt; fend != frm_end; ++fend)
1344 if (*fend == 0)
1345 break;
1346 }
1347 }
1348 return frm_nxt == frm_end ? ok : partial;
1349}
1350
1351codecvt<wchar_t, char, mbstate_t>::result
1352codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001353 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1355{
1356 // look for first internal null in frm
1357 const extern_type* fend = frm;
1358 for (; fend != frm_end; ++fend)
1359 if (*fend == 0)
1360 break;
1361 // loop over all null-terminated sequences in frm
1362 to_nxt = to;
1363 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1364 {
1365 // save state in case needed to reover to_nxt on error
1366 mbstate_t save_state = st;
Howard Hinnantd318d492011-06-30 14:21:55 +00001367 size_t n = with_locale::mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001368 if (n == size_t(-1))
1369 {
1370 // need to recover to_nxt
1371 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1372 {
Howard Hinnantd318d492011-06-30 14:21:55 +00001373 n = with_locale::mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001374 switch (n)
1375 {
1376 case 0:
1377 ++frm;
1378 break;
1379 case -1:
1380 frm_nxt = frm;
1381 return error;
1382 case -2:
1383 frm_nxt = frm;
1384 return partial;
1385 default:
1386 frm += n;
1387 break;
1388 }
1389 }
1390 frm_nxt = frm;
1391 return frm_nxt == frm_end ? ok : partial;
1392 }
1393 if (n == 0)
1394 return error;
1395 to_nxt += n;
1396 if (to_nxt == to_end)
1397 break;
1398 if (fend != frm_end) // set up next null terminated sequence
1399 {
1400 // Try to write the terminating null
Howard Hinnantd318d492011-06-30 14:21:55 +00001401 n = with_locale::mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001402 if (n != 0) // on error
1403 return error;
1404 ++to_nxt;
1405 ++frm_nxt;
1406 // look for next null in frm
1407 for (fend = frm_nxt; fend != frm_end; ++fend)
1408 if (*fend == 0)
1409 break;
1410 }
1411 }
1412 return frm_nxt == frm_end ? ok : partial;
1413}
1414
1415codecvt<wchar_t, char, mbstate_t>::result
1416codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1417 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1418{
1419 to_nxt = to;
1420 extern_type tmp[MB_LEN_MAX];
Howard Hinnantd318d492011-06-30 14:21:55 +00001421 size_t n = with_locale::wcrtomb_l(tmp, intern_type(), &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001422 if (n == size_t(-1) || n == 0) // on error
1423 return error;
1424 --n;
1425 if (n > to_end-to_nxt) // is there room?
1426 return partial;
1427 for (extern_type* p = tmp; n; --n) // write it
1428 *to_nxt++ = *p++;
1429 return ok;
1430}
1431
1432int
Howard Hinnantc9834542011-05-31 15:34:58 +00001433codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001434{
Howard Hinnantd318d492011-06-30 14:21:55 +00001435 if (with_locale::mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001436 {
1437 // stateless encoding
Howard Hinnantd318d492011-06-30 14:21:55 +00001438 if (__l == 0 || with_locale::mb_cur_max_l(__l) == 1) // there are no known constant length encodings
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001439 return 1; // which take more than 1 char to form a wchar_t
1440 return 0;
1441 }
1442 return -1;
1443}
1444
1445bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001446codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001447{
1448 return false;
1449}
1450
1451int
1452codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1453 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1454{
1455 int nbytes = 0;
1456 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1457 {
Howard Hinnantd318d492011-06-30 14:21:55 +00001458 size_t n = with_locale::mbrlen_l(frm, frm_end-frm, &st, __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001459 switch (n)
1460 {
1461 case 0:
1462 ++nbytes;
1463 ++frm;
1464 break;
1465 case -1:
1466 case -2:
1467 return nbytes;
1468 default:
1469 nbytes += n;
1470 frm += n;
1471 break;
1472 }
1473 }
1474 return nbytes;
1475}
1476
1477int
Howard Hinnantc9834542011-05-31 15:34:58 +00001478codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001479{
Howard Hinnantd318d492011-06-30 14:21:55 +00001480 return __l == 0 ? 1 : with_locale::mb_cur_max_l(__l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001481}
1482
1483// Valid UTF ranges
1484// UTF-32 UTF-16 UTF-8 # of code points
1485// first second first second third fourth
1486// 000000 - 00007F 0000 - 007F 00 - 7F 127
1487// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1488// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1489// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1490// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1491// 00D800 - 00DFFF invalid
1492// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1493// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1494// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1495// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1496
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00001497static
1498codecvt_base::result
1499utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1500 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1501 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1502{
1503 frm_nxt = frm;
1504 to_nxt = to;
1505 if (mode & generate_header)
1506 {
1507 if (to_end-to_nxt < 3)
1508 return codecvt_base::partial;
1509 *to_nxt++ = static_cast<uint8_t>(0xEF);
1510 *to_nxt++ = static_cast<uint8_t>(0xBB);
1511 *to_nxt++ = static_cast<uint8_t>(0xBF);
1512 }
1513 for (; frm_nxt < frm_end; ++frm_nxt)
1514 {
1515 uint16_t wc1 = *frm_nxt;
1516 if (wc1 > Maxcode)
1517 return codecvt_base::error;
1518 if (wc1 < 0x0080)
1519 {
1520 if (to_end-to_nxt < 1)
1521 return codecvt_base::partial;
1522 *to_nxt++ = static_cast<uint8_t>(wc1);
1523 }
1524 else if (wc1 < 0x0800)
1525 {
1526 if (to_end-to_nxt < 2)
1527 return codecvt_base::partial;
1528 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1529 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1530 }
1531 else if (wc1 < 0xD800)
1532 {
1533 if (to_end-to_nxt < 3)
1534 return codecvt_base::partial;
1535 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1536 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1537 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1538 }
1539 else if (wc1 < 0xDC00)
1540 {
1541 if (frm_end-frm_nxt < 2)
1542 return codecvt_base::partial;
1543 uint16_t wc2 = frm_nxt[1];
1544 if ((wc2 & 0xFC00) != 0xDC00)
1545 return codecvt_base::error;
1546 if (to_end-to_nxt < 4)
1547 return codecvt_base::partial;
1548 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1549 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1550 return codecvt_base::error;
1551 ++frm_nxt;
1552 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1553 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1554 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1555 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1556 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1557 }
1558 else if (wc1 < 0xE000)
1559 {
1560 return codecvt_base::error;
1561 }
1562 else
1563 {
1564 if (to_end-to_nxt < 3)
1565 return codecvt_base::partial;
1566 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1567 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1568 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1569 }
1570 }
1571 return codecvt_base::ok;
1572}
1573
1574static
1575codecvt_base::result
1576utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1577 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1578 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1579{
1580 frm_nxt = frm;
1581 to_nxt = to;
1582 if (mode & generate_header)
1583 {
1584 if (to_end-to_nxt < 3)
1585 return codecvt_base::partial;
1586 *to_nxt++ = static_cast<uint8_t>(0xEF);
1587 *to_nxt++ = static_cast<uint8_t>(0xBB);
1588 *to_nxt++ = static_cast<uint8_t>(0xBF);
1589 }
1590 for (; frm_nxt < frm_end; ++frm_nxt)
1591 {
1592 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1593 if (wc1 > Maxcode)
1594 return codecvt_base::error;
1595 if (wc1 < 0x0080)
1596 {
1597 if (to_end-to_nxt < 1)
1598 return codecvt_base::partial;
1599 *to_nxt++ = static_cast<uint8_t>(wc1);
1600 }
1601 else if (wc1 < 0x0800)
1602 {
1603 if (to_end-to_nxt < 2)
1604 return codecvt_base::partial;
1605 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1606 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1607 }
1608 else if (wc1 < 0xD800)
1609 {
1610 if (to_end-to_nxt < 3)
1611 return codecvt_base::partial;
1612 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1613 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1614 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1615 }
1616 else if (wc1 < 0xDC00)
1617 {
1618 if (frm_end-frm_nxt < 2)
1619 return codecvt_base::partial;
1620 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1621 if ((wc2 & 0xFC00) != 0xDC00)
1622 return codecvt_base::error;
1623 if (to_end-to_nxt < 4)
1624 return codecvt_base::partial;
1625 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1626 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1627 return codecvt_base::error;
1628 ++frm_nxt;
1629 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1630 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1631 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1632 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1633 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1634 }
1635 else if (wc1 < 0xE000)
1636 {
1637 return codecvt_base::error;
1638 }
1639 else
1640 {
1641 if (to_end-to_nxt < 3)
1642 return codecvt_base::partial;
1643 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1644 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1645 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1646 }
1647 }
1648 return codecvt_base::ok;
1649}
1650
1651static
1652codecvt_base::result
1653utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1654 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1655 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1656{
1657 frm_nxt = frm;
1658 to_nxt = to;
1659 if (mode & consume_header)
1660 {
1661 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1662 frm_nxt[2] == 0xBF)
1663 frm_nxt += 3;
1664 }
1665 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1666 {
1667 uint8_t c1 = *frm_nxt;
1668 if (c1 > Maxcode)
1669 return codecvt_base::error;
1670 if (c1 < 0x80)
1671 {
1672 *to_nxt = static_cast<uint16_t>(c1);
1673 ++frm_nxt;
1674 }
1675 else if (c1 < 0xC2)
1676 {
1677 return codecvt_base::error;
1678 }
1679 else if (c1 < 0xE0)
1680 {
1681 if (frm_end-frm_nxt < 2)
1682 return codecvt_base::partial;
1683 uint8_t c2 = frm_nxt[1];
1684 if ((c2 & 0xC0) != 0x80)
1685 return codecvt_base::error;
1686 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1687 if (t > Maxcode)
1688 return codecvt_base::error;
1689 *to_nxt = t;
1690 frm_nxt += 2;
1691 }
1692 else if (c1 < 0xF0)
1693 {
1694 if (frm_end-frm_nxt < 3)
1695 return codecvt_base::partial;
1696 uint8_t c2 = frm_nxt[1];
1697 uint8_t c3 = frm_nxt[2];
1698 switch (c1)
1699 {
1700 case 0xE0:
1701 if ((c2 & 0xE0) != 0xA0)
1702 return codecvt_base::error;
1703 break;
1704 case 0xED:
1705 if ((c2 & 0xE0) != 0x80)
1706 return codecvt_base::error;
1707 break;
1708 default:
1709 if ((c2 & 0xC0) != 0x80)
1710 return codecvt_base::error;
1711 break;
1712 }
1713 if ((c3 & 0xC0) != 0x80)
1714 return codecvt_base::error;
1715 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1716 | ((c2 & 0x3F) << 6)
1717 | (c3 & 0x3F));
1718 if (t > Maxcode)
1719 return codecvt_base::error;
1720 *to_nxt = t;
1721 frm_nxt += 3;
1722 }
1723 else if (c1 < 0xF5)
1724 {
1725 if (frm_end-frm_nxt < 4)
1726 return codecvt_base::partial;
1727 uint8_t c2 = frm_nxt[1];
1728 uint8_t c3 = frm_nxt[2];
1729 uint8_t c4 = frm_nxt[3];
1730 switch (c1)
1731 {
1732 case 0xF0:
1733 if (!(0x90 <= c2 && c2 <= 0xBF))
1734 return codecvt_base::error;
1735 break;
1736 case 0xF4:
1737 if ((c2 & 0xF0) != 0x80)
1738 return codecvt_base::error;
1739 break;
1740 default:
1741 if ((c2 & 0xC0) != 0x80)
1742 return codecvt_base::error;
1743 break;
1744 }
1745 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1746 return codecvt_base::error;
1747 if (to_end-to_nxt < 2)
1748 return codecvt_base::partial;
1749 if (((((unsigned long)c1 & 7) << 18) +
1750 (((unsigned long)c2 & 0x3F) << 12) +
1751 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1752 return codecvt_base::error;
1753 *to_nxt = static_cast<uint16_t>(
1754 0xD800
1755 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1756 | ((c2 & 0x0F) << 2)
1757 | ((c3 & 0x30) >> 4));
1758 *++to_nxt = static_cast<uint16_t>(
1759 0xDC00
1760 | ((c3 & 0x0F) << 6)
1761 | (c4 & 0x3F));
1762 frm_nxt += 4;
1763 }
1764 else
1765 {
1766 return codecvt_base::error;
1767 }
1768 }
1769 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1770}
1771
1772static
1773codecvt_base::result
1774utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1775 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1776 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1777{
1778 frm_nxt = frm;
1779 to_nxt = to;
1780 if (mode & consume_header)
1781 {
1782 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1783 frm_nxt[2] == 0xBF)
1784 frm_nxt += 3;
1785 }
1786 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1787 {
1788 uint8_t c1 = *frm_nxt;
1789 if (c1 > Maxcode)
1790 return codecvt_base::error;
1791 if (c1 < 0x80)
1792 {
1793 *to_nxt = static_cast<uint32_t>(c1);
1794 ++frm_nxt;
1795 }
1796 else if (c1 < 0xC2)
1797 {
1798 return codecvt_base::error;
1799 }
1800 else if (c1 < 0xE0)
1801 {
1802 if (frm_end-frm_nxt < 2)
1803 return codecvt_base::partial;
1804 uint8_t c2 = frm_nxt[1];
1805 if ((c2 & 0xC0) != 0x80)
1806 return codecvt_base::error;
1807 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1808 if (t > Maxcode)
1809 return codecvt_base::error;
1810 *to_nxt = static_cast<uint32_t>(t);
1811 frm_nxt += 2;
1812 }
1813 else if (c1 < 0xF0)
1814 {
1815 if (frm_end-frm_nxt < 3)
1816 return codecvt_base::partial;
1817 uint8_t c2 = frm_nxt[1];
1818 uint8_t c3 = frm_nxt[2];
1819 switch (c1)
1820 {
1821 case 0xE0:
1822 if ((c2 & 0xE0) != 0xA0)
1823 return codecvt_base::error;
1824 break;
1825 case 0xED:
1826 if ((c2 & 0xE0) != 0x80)
1827 return codecvt_base::error;
1828 break;
1829 default:
1830 if ((c2 & 0xC0) != 0x80)
1831 return codecvt_base::error;
1832 break;
1833 }
1834 if ((c3 & 0xC0) != 0x80)
1835 return codecvt_base::error;
1836 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1837 | ((c2 & 0x3F) << 6)
1838 | (c3 & 0x3F));
1839 if (t > Maxcode)
1840 return codecvt_base::error;
1841 *to_nxt = static_cast<uint32_t>(t);
1842 frm_nxt += 3;
1843 }
1844 else if (c1 < 0xF5)
1845 {
1846 if (frm_end-frm_nxt < 4)
1847 return codecvt_base::partial;
1848 uint8_t c2 = frm_nxt[1];
1849 uint8_t c3 = frm_nxt[2];
1850 uint8_t c4 = frm_nxt[3];
1851 switch (c1)
1852 {
1853 case 0xF0:
1854 if (!(0x90 <= c2 && c2 <= 0xBF))
1855 return codecvt_base::error;
1856 break;
1857 case 0xF4:
1858 if ((c2 & 0xF0) != 0x80)
1859 return codecvt_base::error;
1860 break;
1861 default:
1862 if ((c2 & 0xC0) != 0x80)
1863 return codecvt_base::error;
1864 break;
1865 }
1866 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1867 return codecvt_base::error;
1868 if (to_end-to_nxt < 2)
1869 return codecvt_base::partial;
1870 if (((((unsigned long)c1 & 7) << 18) +
1871 (((unsigned long)c2 & 0x3F) << 12) +
1872 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1873 return codecvt_base::error;
1874 *to_nxt = static_cast<uint32_t>(
1875 0xD800
1876 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1877 | ((c2 & 0x0F) << 2)
1878 | ((c3 & 0x30) >> 4));
1879 *++to_nxt = static_cast<uint32_t>(
1880 0xDC00
1881 | ((c3 & 0x0F) << 6)
1882 | (c4 & 0x3F));
1883 frm_nxt += 4;
1884 }
1885 else
1886 {
1887 return codecvt_base::error;
1888 }
1889 }
1890 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1891}
1892
1893static
1894int
1895utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1896 size_t mx, unsigned long Maxcode = 0x10FFFF,
1897 codecvt_mode mode = codecvt_mode(0))
1898{
1899 const uint8_t* frm_nxt = frm;
1900 if (mode & consume_header)
1901 {
1902 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1903 frm_nxt[2] == 0xBF)
1904 frm_nxt += 3;
1905 }
1906 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1907 {
1908 uint8_t c1 = *frm_nxt;
1909 if (c1 > Maxcode)
1910 break;
1911 if (c1 < 0x80)
1912 {
1913 ++frm_nxt;
1914 }
1915 else if (c1 < 0xC2)
1916 {
1917 break;
1918 }
1919 else if (c1 < 0xE0)
1920 {
1921 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1922 break;
1923 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1924 if (t > Maxcode)
1925 break;
1926 frm_nxt += 2;
1927 }
1928 else if (c1 < 0xF0)
1929 {
1930 if (frm_end-frm_nxt < 3)
1931 break;
1932 uint8_t c2 = frm_nxt[1];
1933 uint8_t c3 = frm_nxt[2];
1934 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1935 | ((c2 & 0x3F) << 6)
1936 | (c3 & 0x3F));
1937 switch (c1)
1938 {
1939 case 0xE0:
1940 if ((c2 & 0xE0) != 0xA0)
1941 return static_cast<int>(frm_nxt - frm);
1942 break;
1943 case 0xED:
1944 if ((c2 & 0xE0) != 0x80)
1945 return static_cast<int>(frm_nxt - frm);
1946 break;
1947 default:
1948 if ((c2 & 0xC0) != 0x80)
1949 return static_cast<int>(frm_nxt - frm);
1950 break;
1951 }
1952 if ((c3 & 0xC0) != 0x80)
1953 break;
1954 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
1955 break;
1956 frm_nxt += 3;
1957 }
1958 else if (c1 < 0xF5)
1959 {
1960 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
1961 break;
1962 uint8_t c2 = frm_nxt[1];
1963 uint8_t c3 = frm_nxt[2];
1964 uint8_t c4 = frm_nxt[3];
1965 switch (c1)
1966 {
1967 case 0xF0:
1968 if (!(0x90 <= c2 && c2 <= 0xBF))
1969 return static_cast<int>(frm_nxt - frm);
1970 break;
1971 case 0xF4:
1972 if ((c2 & 0xF0) != 0x80)
1973 return static_cast<int>(frm_nxt - frm);
1974 break;
1975 default:
1976 if ((c2 & 0xC0) != 0x80)
1977 return static_cast<int>(frm_nxt - frm);
1978 break;
1979 }
1980 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1981 break;
1982 if (((((unsigned long)c1 & 7) << 18) +
1983 (((unsigned long)c2 & 0x3F) << 12) +
1984 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1985 break;
1986 ++nchar16_t;
1987 frm_nxt += 4;
1988 }
1989 else
1990 {
1991 break;
1992 }
1993 }
1994 return static_cast<int>(frm_nxt - frm);
1995}
1996
1997static
1998codecvt_base::result
1999ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2000 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2001 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2002{
2003 frm_nxt = frm;
2004 to_nxt = to;
2005 if (mode & generate_header)
2006 {
2007 if (to_end-to_nxt < 3)
2008 return codecvt_base::partial;
2009 *to_nxt++ = static_cast<uint8_t>(0xEF);
2010 *to_nxt++ = static_cast<uint8_t>(0xBB);
2011 *to_nxt++ = static_cast<uint8_t>(0xBF);
2012 }
2013 for (; frm_nxt < frm_end; ++frm_nxt)
2014 {
2015 uint32_t wc = *frm_nxt;
2016 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2017 return codecvt_base::error;
2018 if (wc < 0x000080)
2019 {
2020 if (to_end-to_nxt < 1)
2021 return codecvt_base::partial;
2022 *to_nxt++ = static_cast<uint8_t>(wc);
2023 }
2024 else if (wc < 0x000800)
2025 {
2026 if (to_end-to_nxt < 2)
2027 return codecvt_base::partial;
2028 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2029 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2030 }
2031 else if (wc < 0x010000)
2032 {
2033 if (to_end-to_nxt < 3)
2034 return codecvt_base::partial;
2035 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2036 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2037 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2038 }
2039 else // if (wc < 0x110000)
2040 {
2041 if (to_end-to_nxt < 4)
2042 return codecvt_base::partial;
2043 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2044 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2045 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2046 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2047 }
2048 }
2049 return codecvt_base::ok;
2050}
2051
2052static
2053codecvt_base::result
2054utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2055 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2056 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2057{
2058 frm_nxt = frm;
2059 to_nxt = to;
2060 if (mode & consume_header)
2061 {
2062 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2063 frm_nxt[2] == 0xBF)
2064 frm_nxt += 3;
2065 }
2066 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2067 {
2068 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2069 if (c1 < 0x80)
2070 {
2071 if (c1 > Maxcode)
2072 return codecvt_base::error;
2073 *to_nxt = static_cast<uint32_t>(c1);
2074 ++frm_nxt;
2075 }
2076 else if (c1 < 0xC2)
2077 {
2078 return codecvt_base::error;
2079 }
2080 else if (c1 < 0xE0)
2081 {
2082 if (frm_end-frm_nxt < 2)
2083 return codecvt_base::partial;
2084 uint8_t c2 = frm_nxt[1];
2085 if ((c2 & 0xC0) != 0x80)
2086 return codecvt_base::error;
2087 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2088 | (c2 & 0x3F));
2089 if (t > Maxcode)
2090 return codecvt_base::error;
2091 *to_nxt = t;
2092 frm_nxt += 2;
2093 }
2094 else if (c1 < 0xF0)
2095 {
2096 if (frm_end-frm_nxt < 3)
2097 return codecvt_base::partial;
2098 uint8_t c2 = frm_nxt[1];
2099 uint8_t c3 = frm_nxt[2];
2100 switch (c1)
2101 {
2102 case 0xE0:
2103 if ((c2 & 0xE0) != 0xA0)
2104 return codecvt_base::error;
2105 break;
2106 case 0xED:
2107 if ((c2 & 0xE0) != 0x80)
2108 return codecvt_base::error;
2109 break;
2110 default:
2111 if ((c2 & 0xC0) != 0x80)
2112 return codecvt_base::error;
2113 break;
2114 }
2115 if ((c3 & 0xC0) != 0x80)
2116 return codecvt_base::error;
2117 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2118 | ((c2 & 0x3F) << 6)
2119 | (c3 & 0x3F));
2120 if (t > Maxcode)
2121 return codecvt_base::error;
2122 *to_nxt = t;
2123 frm_nxt += 3;
2124 }
2125 else if (c1 < 0xF5)
2126 {
2127 if (frm_end-frm_nxt < 4)
2128 return codecvt_base::partial;
2129 uint8_t c2 = frm_nxt[1];
2130 uint8_t c3 = frm_nxt[2];
2131 uint8_t c4 = frm_nxt[3];
2132 switch (c1)
2133 {
2134 case 0xF0:
2135 if (!(0x90 <= c2 && c2 <= 0xBF))
2136 return codecvt_base::error;
2137 break;
2138 case 0xF4:
2139 if ((c2 & 0xF0) != 0x80)
2140 return codecvt_base::error;
2141 break;
2142 default:
2143 if ((c2 & 0xC0) != 0x80)
2144 return codecvt_base::error;
2145 break;
2146 }
2147 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2148 return codecvt_base::error;
2149 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2150 | ((c2 & 0x3F) << 12)
2151 | ((c3 & 0x3F) << 6)
2152 | (c4 & 0x3F));
2153 if (t > Maxcode)
2154 return codecvt_base::error;
2155 *to_nxt = t;
2156 frm_nxt += 4;
2157 }
2158 else
2159 {
2160 return codecvt_base::error;
2161 }
2162 }
2163 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2164}
2165
2166static
2167int
2168utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2169 size_t mx, unsigned long Maxcode = 0x10FFFF,
2170 codecvt_mode mode = codecvt_mode(0))
2171{
2172 const uint8_t* frm_nxt = frm;
2173 if (mode & consume_header)
2174 {
2175 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2176 frm_nxt[2] == 0xBF)
2177 frm_nxt += 3;
2178 }
2179 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2180 {
2181 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2182 if (c1 < 0x80)
2183 {
2184 if (c1 > Maxcode)
2185 break;
2186 ++frm_nxt;
2187 }
2188 else if (c1 < 0xC2)
2189 {
2190 break;
2191 }
2192 else if (c1 < 0xE0)
2193 {
2194 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2195 break;
2196 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2197 break;
2198 frm_nxt += 2;
2199 }
2200 else if (c1 < 0xF0)
2201 {
2202 if (frm_end-frm_nxt < 3)
2203 break;
2204 uint8_t c2 = frm_nxt[1];
2205 uint8_t c3 = frm_nxt[2];
2206 switch (c1)
2207 {
2208 case 0xE0:
2209 if ((c2 & 0xE0) != 0xA0)
2210 return static_cast<int>(frm_nxt - frm);
2211 break;
2212 case 0xED:
2213 if ((c2 & 0xE0) != 0x80)
2214 return static_cast<int>(frm_nxt - frm);
2215 break;
2216 default:
2217 if ((c2 & 0xC0) != 0x80)
2218 return static_cast<int>(frm_nxt - frm);
2219 break;
2220 }
2221 if ((c3 & 0xC0) != 0x80)
2222 break;
2223 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2224 break;
2225 frm_nxt += 3;
2226 }
2227 else if (c1 < 0xF5)
2228 {
2229 if (frm_end-frm_nxt < 4)
2230 break;
2231 uint8_t c2 = frm_nxt[1];
2232 uint8_t c3 = frm_nxt[2];
2233 uint8_t c4 = frm_nxt[3];
2234 switch (c1)
2235 {
2236 case 0xF0:
2237 if (!(0x90 <= c2 && c2 <= 0xBF))
2238 return static_cast<int>(frm_nxt - frm);
2239 break;
2240 case 0xF4:
2241 if ((c2 & 0xF0) != 0x80)
2242 return static_cast<int>(frm_nxt - frm);
2243 break;
2244 default:
2245 if ((c2 & 0xC0) != 0x80)
2246 return static_cast<int>(frm_nxt - frm);
2247 break;
2248 }
2249 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2250 break;
2251 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2252 | ((c2 & 0x3F) << 12)
2253 | ((c3 & 0x3F) << 6)
2254 | (c4 & 0x3F));
2255 if ((((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
2256 ((c3 & 0x3F) << 6) | (c4 & 0x3F)) > Maxcode)
2257 break;
2258 frm_nxt += 4;
2259 }
2260 else
2261 {
2262 break;
2263 }
2264 }
2265 return static_cast<int>(frm_nxt - frm);
2266}
2267
2268static
2269codecvt_base::result
2270ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2271 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2272 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2273{
2274 frm_nxt = frm;
2275 to_nxt = to;
2276 if (mode & generate_header)
2277 {
2278 if (to_end-to_nxt < 3)
2279 return codecvt_base::partial;
2280 *to_nxt++ = static_cast<uint8_t>(0xEF);
2281 *to_nxt++ = static_cast<uint8_t>(0xBB);
2282 *to_nxt++ = static_cast<uint8_t>(0xBF);
2283 }
2284 for (; frm_nxt < frm_end; ++frm_nxt)
2285 {
2286 uint16_t wc = *frm_nxt;
2287 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2288 return codecvt_base::error;
2289 if (wc < 0x0080)
2290 {
2291 if (to_end-to_nxt < 1)
2292 return codecvt_base::partial;
2293 *to_nxt++ = static_cast<uint8_t>(wc);
2294 }
2295 else if (wc < 0x0800)
2296 {
2297 if (to_end-to_nxt < 2)
2298 return codecvt_base::partial;
2299 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2300 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2301 }
2302 else // if (wc <= 0xFFFF)
2303 {
2304 if (to_end-to_nxt < 3)
2305 return codecvt_base::partial;
2306 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2307 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2308 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2309 }
2310 }
2311 return codecvt_base::ok;
2312}
2313
2314static
2315codecvt_base::result
2316utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2317 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2318 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2319{
2320 frm_nxt = frm;
2321 to_nxt = to;
2322 if (mode & consume_header)
2323 {
2324 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2325 frm_nxt[2] == 0xBF)
2326 frm_nxt += 3;
2327 }
2328 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2329 {
2330 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2331 if (c1 < 0x80)
2332 {
2333 if (c1 > Maxcode)
2334 return codecvt_base::error;
2335 *to_nxt = static_cast<uint16_t>(c1);
2336 ++frm_nxt;
2337 }
2338 else if (c1 < 0xC2)
2339 {
2340 return codecvt_base::error;
2341 }
2342 else if (c1 < 0xE0)
2343 {
2344 if (frm_end-frm_nxt < 2)
2345 return codecvt_base::partial;
2346 uint8_t c2 = frm_nxt[1];
2347 if ((c2 & 0xC0) != 0x80)
2348 return codecvt_base::error;
2349 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2350 | (c2 & 0x3F));
2351 if (t > Maxcode)
2352 return codecvt_base::error;
2353 *to_nxt = t;
2354 frm_nxt += 2;
2355 }
2356 else if (c1 < 0xF0)
2357 {
2358 if (frm_end-frm_nxt < 3)
2359 return codecvt_base::partial;
2360 uint8_t c2 = frm_nxt[1];
2361 uint8_t c3 = frm_nxt[2];
2362 switch (c1)
2363 {
2364 case 0xE0:
2365 if ((c2 & 0xE0) != 0xA0)
2366 return codecvt_base::error;
2367 break;
2368 case 0xED:
2369 if ((c2 & 0xE0) != 0x80)
2370 return codecvt_base::error;
2371 break;
2372 default:
2373 if ((c2 & 0xC0) != 0x80)
2374 return codecvt_base::error;
2375 break;
2376 }
2377 if ((c3 & 0xC0) != 0x80)
2378 return codecvt_base::error;
2379 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2380 | ((c2 & 0x3F) << 6)
2381 | (c3 & 0x3F));
2382 if (t > Maxcode)
2383 return codecvt_base::error;
2384 *to_nxt = t;
2385 frm_nxt += 3;
2386 }
2387 else
2388 {
2389 return codecvt_base::error;
2390 }
2391 }
2392 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2393}
2394
2395static
2396int
2397utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2398 size_t mx, unsigned long Maxcode = 0x10FFFF,
2399 codecvt_mode mode = codecvt_mode(0))
2400{
2401 const uint8_t* frm_nxt = frm;
2402 if (mode & consume_header)
2403 {
2404 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2405 frm_nxt[2] == 0xBF)
2406 frm_nxt += 3;
2407 }
2408 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2409 {
2410 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2411 if (c1 < 0x80)
2412 {
2413 if (c1 > Maxcode)
2414 break;
2415 ++frm_nxt;
2416 }
2417 else if (c1 < 0xC2)
2418 {
2419 break;
2420 }
2421 else if (c1 < 0xE0)
2422 {
2423 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2424 break;
2425 if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
2426 break;
2427 frm_nxt += 2;
2428 }
2429 else if (c1 < 0xF0)
2430 {
2431 if (frm_end-frm_nxt < 3)
2432 break;
2433 uint8_t c2 = frm_nxt[1];
2434 uint8_t c3 = frm_nxt[2];
2435 switch (c1)
2436 {
2437 case 0xE0:
2438 if ((c2 & 0xE0) != 0xA0)
2439 return static_cast<int>(frm_nxt - frm);
2440 break;
2441 case 0xED:
2442 if ((c2 & 0xE0) != 0x80)
2443 return static_cast<int>(frm_nxt - frm);
2444 break;
2445 default:
2446 if ((c2 & 0xC0) != 0x80)
2447 return static_cast<int>(frm_nxt - frm);
2448 break;
2449 }
2450 if ((c3 & 0xC0) != 0x80)
2451 break;
2452 if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
2453 break;
2454 frm_nxt += 3;
2455 }
2456 else
2457 {
2458 break;
2459 }
2460 }
2461 return static_cast<int>(frm_nxt - frm);
2462}
2463
2464static
2465codecvt_base::result
2466ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2467 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2468 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2469{
2470 frm_nxt = frm;
2471 to_nxt = to;
2472 if (mode & generate_header)
2473 {
2474 if (to_end-to_nxt < 2)
2475 return codecvt_base::partial;
2476 *to_nxt++ = static_cast<uint8_t>(0xFE);
2477 *to_nxt++ = static_cast<uint8_t>(0xFF);
2478 }
2479 for (; frm_nxt < frm_end; ++frm_nxt)
2480 {
2481 uint32_t wc = *frm_nxt;
2482 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2483 return codecvt_base::error;
2484 if (wc < 0x010000)
2485 {
2486 if (to_end-to_nxt < 2)
2487 return codecvt_base::partial;
2488 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2489 *to_nxt++ = static_cast<uint8_t>(wc);
2490 }
2491 else
2492 {
2493 if (to_end-to_nxt < 4)
2494 return codecvt_base::partial;
2495 uint16_t t = static_cast<uint16_t>(
2496 0xD800
2497 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2498 | ((wc & 0x00FC00) >> 10));
2499 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2500 *to_nxt++ = static_cast<uint8_t>(t);
2501 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2502 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2503 *to_nxt++ = static_cast<uint8_t>(t);
2504 }
2505 }
2506 return codecvt_base::ok;
2507}
2508
2509static
2510codecvt_base::result
2511utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2512 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2513 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2514{
2515 frm_nxt = frm;
2516 to_nxt = to;
2517 if (mode & consume_header)
2518 {
2519 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2520 frm_nxt += 2;
2521 }
2522 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2523 {
2524 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2525 if ((c1 & 0xFC00) == 0xDC00)
2526 return codecvt_base::error;
2527 if ((c1 & 0xFC00) != 0xD800)
2528 {
2529 if (c1 > Maxcode)
2530 return codecvt_base::error;
2531 *to_nxt = static_cast<uint32_t>(c1);
2532 frm_nxt += 2;
2533 }
2534 else
2535 {
2536 if (frm_end-frm_nxt < 4)
2537 return codecvt_base::partial;
2538 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2539 if ((c2 & 0xFC00) != 0xDC00)
2540 return codecvt_base::error;
2541 uint32_t t = static_cast<uint32_t>(
2542 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2543 | ((c1 & 0x003F) << 10)
2544 | (c2 & 0x03FF));
2545 if (t > Maxcode)
2546 return codecvt_base::error;
2547 *to_nxt = t;
2548 frm_nxt += 4;
2549 }
2550 }
2551 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2552}
2553
2554static
2555int
2556utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2557 size_t mx, unsigned long Maxcode = 0x10FFFF,
2558 codecvt_mode mode = codecvt_mode(0))
2559{
2560 const uint8_t* frm_nxt = frm;
2561 frm_nxt = frm;
2562 if (mode & consume_header)
2563 {
2564 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2565 frm_nxt += 2;
2566 }
2567 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2568 {
2569 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2570 if ((c1 & 0xFC00) == 0xDC00)
2571 break;
2572 if ((c1 & 0xFC00) != 0xD800)
2573 {
2574 if (c1 > Maxcode)
2575 break;
2576 frm_nxt += 2;
2577 }
2578 else
2579 {
2580 if (frm_end-frm_nxt < 4)
2581 break;
2582 uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
2583 if ((c2 & 0xFC00) != 0xDC00)
2584 break;
2585 uint32_t t = static_cast<uint32_t>(
2586 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2587 | ((c1 & 0x003F) << 10)
2588 | (c2 & 0x03FF));
2589 if (t > Maxcode)
2590 break;
2591 frm_nxt += 4;
2592 }
2593 }
2594 return static_cast<int>(frm_nxt - frm);
2595}
2596
2597static
2598codecvt_base::result
2599ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2600 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2601 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2602{
2603 frm_nxt = frm;
2604 to_nxt = to;
2605 if (mode & generate_header)
2606 {
2607 if (to_end-to_nxt < 2)
2608 return codecvt_base::partial;
2609 *to_nxt++ = static_cast<uint8_t>(0xFF);
2610 *to_nxt++ = static_cast<uint8_t>(0xFE);
2611 }
2612 for (; frm_nxt < frm_end; ++frm_nxt)
2613 {
2614 uint32_t wc = *frm_nxt;
2615 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2616 return codecvt_base::error;
2617 if (wc < 0x010000)
2618 {
2619 if (to_end-to_nxt < 2)
2620 return codecvt_base::partial;
2621 *to_nxt++ = static_cast<uint8_t>(wc);
2622 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2623 }
2624 else
2625 {
2626 if (to_end-to_nxt < 4)
2627 return codecvt_base::partial;
2628 uint16_t t = static_cast<uint16_t>(
2629 0xD800
2630 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2631 | ((wc & 0x00FC00) >> 10));
2632 *to_nxt++ = static_cast<uint8_t>(t);
2633 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2634 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2635 *to_nxt++ = static_cast<uint8_t>(t);
2636 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2637 }
2638 }
2639 return codecvt_base::ok;
2640}
2641
2642static
2643codecvt_base::result
2644utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2645 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2646 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2647{
2648 frm_nxt = frm;
2649 to_nxt = to;
2650 if (mode & consume_header)
2651 {
2652 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2653 frm_nxt += 2;
2654 }
2655 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2656 {
2657 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2658 if ((c1 & 0xFC00) == 0xDC00)
2659 return codecvt_base::error;
2660 if ((c1 & 0xFC00) != 0xD800)
2661 {
2662 if (c1 > Maxcode)
2663 return codecvt_base::error;
2664 *to_nxt = static_cast<uint32_t>(c1);
2665 frm_nxt += 2;
2666 }
2667 else
2668 {
2669 if (frm_end-frm_nxt < 4)
2670 return codecvt_base::partial;
2671 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2672 if ((c2 & 0xFC00) != 0xDC00)
2673 return codecvt_base::error;
2674 uint32_t t = static_cast<uint32_t>(
2675 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2676 | ((c1 & 0x003F) << 10)
2677 | (c2 & 0x03FF));
2678 if (t > Maxcode)
2679 return codecvt_base::error;
2680 *to_nxt = t;
2681 frm_nxt += 4;
2682 }
2683 }
2684 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2685}
2686
2687static
2688int
2689utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2690 size_t mx, unsigned long Maxcode = 0x10FFFF,
2691 codecvt_mode mode = codecvt_mode(0))
2692{
2693 const uint8_t* frm_nxt = frm;
2694 frm_nxt = frm;
2695 if (mode & consume_header)
2696 {
2697 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2698 frm_nxt += 2;
2699 }
2700 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2701 {
2702 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2703 if ((c1 & 0xFC00) == 0xDC00)
2704 break;
2705 if ((c1 & 0xFC00) != 0xD800)
2706 {
2707 if (c1 > Maxcode)
2708 break;
2709 frm_nxt += 2;
2710 }
2711 else
2712 {
2713 if (frm_end-frm_nxt < 4)
2714 break;
2715 uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
2716 if ((c2 & 0xFC00) != 0xDC00)
2717 break;
2718 uint32_t t = static_cast<uint32_t>(
2719 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2720 | ((c1 & 0x003F) << 10)
2721 | (c2 & 0x03FF));
2722 if (t > Maxcode)
2723 break;
2724 frm_nxt += 4;
2725 }
2726 }
2727 return static_cast<int>(frm_nxt - frm);
2728}
2729
2730static
2731codecvt_base::result
2732ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2733 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2734 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2735{
2736 frm_nxt = frm;
2737 to_nxt = to;
2738 if (mode & generate_header)
2739 {
2740 if (to_end-to_nxt < 2)
2741 return codecvt_base::partial;
2742 *to_nxt++ = static_cast<uint8_t>(0xFE);
2743 *to_nxt++ = static_cast<uint8_t>(0xFF);
2744 }
2745 for (; frm_nxt < frm_end; ++frm_nxt)
2746 {
2747 uint16_t wc = *frm_nxt;
2748 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2749 return codecvt_base::error;
2750 if (to_end-to_nxt < 2)
2751 return codecvt_base::partial;
2752 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2753 *to_nxt++ = static_cast<uint8_t>(wc);
2754 }
2755 return codecvt_base::ok;
2756}
2757
2758static
2759codecvt_base::result
2760utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2761 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2762 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2763{
2764 frm_nxt = frm;
2765 to_nxt = to;
2766 if (mode & consume_header)
2767 {
2768 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2769 frm_nxt += 2;
2770 }
2771 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2772 {
2773 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2774 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2775 return codecvt_base::error;
2776 *to_nxt = c1;
2777 frm_nxt += 2;
2778 }
2779 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2780}
2781
2782static
2783int
2784utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2785 size_t mx, unsigned long Maxcode = 0x10FFFF,
2786 codecvt_mode mode = codecvt_mode(0))
2787{
2788 const uint8_t* frm_nxt = frm;
2789 frm_nxt = frm;
2790 if (mode & consume_header)
2791 {
2792 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2793 frm_nxt += 2;
2794 }
2795 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2796 {
2797 uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
2798 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2799 break;
2800 frm_nxt += 2;
2801 }
2802 return static_cast<int>(frm_nxt - frm);
2803}
2804
2805static
2806codecvt_base::result
2807ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2808 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2809 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2810{
2811 frm_nxt = frm;
2812 to_nxt = to;
2813 if (mode & generate_header)
2814 {
2815 if (to_end-to_nxt < 2)
2816 return codecvt_base::partial;
2817 *to_nxt++ = static_cast<uint8_t>(0xFF);
2818 *to_nxt++ = static_cast<uint8_t>(0xFE);
2819 }
2820 for (; frm_nxt < frm_end; ++frm_nxt)
2821 {
2822 uint16_t wc = *frm_nxt;
2823 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2824 return codecvt_base::error;
2825 if (to_end-to_nxt < 2)
2826 return codecvt_base::partial;
2827 *to_nxt++ = static_cast<uint8_t>(wc);
2828 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2829 }
2830 return codecvt_base::ok;
2831}
2832
2833static
2834codecvt_base::result
2835utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2836 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2837 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2838{
2839 frm_nxt = frm;
2840 to_nxt = to;
2841 if (mode & consume_header)
2842 {
2843 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2844 frm_nxt += 2;
2845 }
2846 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2847 {
2848 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2849 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2850 return codecvt_base::error;
2851 *to_nxt = c1;
2852 frm_nxt += 2;
2853 }
2854 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2855}
2856
2857static
2858int
2859utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2860 size_t mx, unsigned long Maxcode = 0x10FFFF,
2861 codecvt_mode mode = codecvt_mode(0))
2862{
2863 const uint8_t* frm_nxt = frm;
2864 frm_nxt = frm;
2865 if (mode & consume_header)
2866 {
2867 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2868 frm_nxt += 2;
2869 }
2870 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2871 {
2872 uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
2873 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2874 break;
2875 frm_nxt += 2;
2876 }
2877 return static_cast<int>(frm_nxt - frm);
2878}
2879
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002880// template <> class codecvt<char16_t, char, mbstate_t>
2881
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002882locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002883
2884codecvt<char16_t, char, mbstate_t>::~codecvt()
2885{
2886}
2887
2888codecvt<char16_t, char, mbstate_t>::result
2889codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002890 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002891 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2892{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002893 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2894 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2895 const uint16_t* _frm_nxt = _frm;
2896 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2897 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2898 uint8_t* _to_nxt = _to;
2899 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2900 frm_nxt = frm + (_frm_nxt - _frm);
2901 to_nxt = to + (_to_nxt - _to);
2902 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002903}
2904
2905codecvt<char16_t, char, mbstate_t>::result
2906codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002907 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002908 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2909{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002910 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2911 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2912 const uint8_t* _frm_nxt = _frm;
2913 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2914 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2915 uint16_t* _to_nxt = _to;
2916 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2917 frm_nxt = frm + (_frm_nxt - _frm);
2918 to_nxt = to + (_to_nxt - _to);
2919 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002920}
2921
2922codecvt<char16_t, char, mbstate_t>::result
2923codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2924 extern_type* to, extern_type*, extern_type*& to_nxt) const
2925{
2926 to_nxt = to;
2927 return noconv;
2928}
2929
2930int
Howard Hinnantc9834542011-05-31 15:34:58 +00002931codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002932{
2933 return 0;
2934}
2935
2936bool
Howard Hinnantc9834542011-05-31 15:34:58 +00002937codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002938{
2939 return false;
2940}
2941
2942int
2943codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2944 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2945{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002946 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2947 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2948 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002949}
2950
2951int
Howard Hinnantc9834542011-05-31 15:34:58 +00002952codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002953{
2954 return 4;
2955}
2956
2957// template <> class codecvt<char32_t, char, mbstate_t>
2958
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002959locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002960
2961codecvt<char32_t, char, mbstate_t>::~codecvt()
2962{
2963}
2964
2965codecvt<char32_t, char, mbstate_t>::result
2966codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002967 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002968 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2969{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002970 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
2971 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
2972 const uint32_t* _frm_nxt = _frm;
2973 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2974 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2975 uint8_t* _to_nxt = _to;
2976 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2977 frm_nxt = frm + (_frm_nxt - _frm);
2978 to_nxt = to + (_to_nxt - _to);
2979 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002980}
2981
2982codecvt<char32_t, char, mbstate_t>::result
2983codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002984 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002985 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2986{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002987 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2988 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2989 const uint8_t* _frm_nxt = _frm;
2990 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
2991 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
2992 uint32_t* _to_nxt = _to;
2993 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2994 frm_nxt = frm + (_frm_nxt - _frm);
2995 to_nxt = to + (_to_nxt - _to);
2996 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002997}
2998
2999codecvt<char32_t, char, mbstate_t>::result
3000codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3001 extern_type* to, extern_type*, extern_type*& to_nxt) const
3002{
3003 to_nxt = to;
3004 return noconv;
3005}
3006
3007int
Howard Hinnantc9834542011-05-31 15:34:58 +00003008codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003009{
3010 return 0;
3011}
3012
3013bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003014codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003015{
3016 return false;
3017}
3018
3019int
3020codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3021 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3022{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003023 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3024 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3025 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003026}
3027
3028int
Howard Hinnantc9834542011-05-31 15:34:58 +00003029codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003030{
3031 return 4;
3032}
3033
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003034// __codecvt_utf8<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003035
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003036__codecvt_utf8<wchar_t>::result
3037__codecvt_utf8<wchar_t>::do_out(state_type&,
3038 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003039 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3040{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003041 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3042 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3043 const uint32_t* _frm_nxt = _frm;
3044 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3045 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3046 uint8_t* _to_nxt = _to;
3047 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3048 _Maxcode_, _Mode_);
3049 frm_nxt = frm + (_frm_nxt - _frm);
3050 to_nxt = to + (_to_nxt - _to);
3051 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003052}
3053
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003054__codecvt_utf8<wchar_t>::result
3055__codecvt_utf8<wchar_t>::do_in(state_type&,
3056 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003057 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3058{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003059 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3060 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3061 const uint8_t* _frm_nxt = _frm;
3062 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3063 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3064 uint32_t* _to_nxt = _to;
3065 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3066 _Maxcode_, _Mode_);
3067 frm_nxt = frm + (_frm_nxt - _frm);
3068 to_nxt = to + (_to_nxt - _to);
3069 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003070}
3071
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003072__codecvt_utf8<wchar_t>::result
3073__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003074 extern_type* to, extern_type*, extern_type*& to_nxt) const
3075{
3076 to_nxt = to;
3077 return noconv;
3078}
3079
3080int
Howard Hinnantc9834542011-05-31 15:34:58 +00003081__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003082{
3083 return 0;
3084}
3085
3086bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003087__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003088{
3089 return false;
3090}
3091
3092int
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003093__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003094 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3095{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003096 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3097 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3098 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003099}
3100
3101int
Howard Hinnantc9834542011-05-31 15:34:58 +00003102__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003103{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003104 if (_Mode_ & consume_header)
3105 return 7;
3106 return 4;
3107}
3108
3109// __codecvt_utf8<char16_t>
3110
3111__codecvt_utf8<char16_t>::result
3112__codecvt_utf8<char16_t>::do_out(state_type&,
3113 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3114 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3115{
3116 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3117 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3118 const uint16_t* _frm_nxt = _frm;
3119 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3120 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3121 uint8_t* _to_nxt = _to;
3122 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3123 _Maxcode_, _Mode_);
3124 frm_nxt = frm + (_frm_nxt - _frm);
3125 to_nxt = to + (_to_nxt - _to);
3126 return r;
3127}
3128
3129__codecvt_utf8<char16_t>::result
3130__codecvt_utf8<char16_t>::do_in(state_type&,
3131 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3132 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3133{
3134 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3135 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3136 const uint8_t* _frm_nxt = _frm;
3137 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3138 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3139 uint16_t* _to_nxt = _to;
3140 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3141 _Maxcode_, _Mode_);
3142 frm_nxt = frm + (_frm_nxt - _frm);
3143 to_nxt = to + (_to_nxt - _to);
3144 return r;
3145}
3146
3147__codecvt_utf8<char16_t>::result
3148__codecvt_utf8<char16_t>::do_unshift(state_type&,
3149 extern_type* to, extern_type*, extern_type*& to_nxt) const
3150{
3151 to_nxt = to;
3152 return noconv;
3153}
3154
3155int
Howard Hinnantc9834542011-05-31 15:34:58 +00003156__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003157{
3158 return 0;
3159}
3160
3161bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003162__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003163{
3164 return false;
3165}
3166
3167int
3168__codecvt_utf8<char16_t>::do_length(state_type&,
3169 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3170{
3171 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3172 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3173 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3174}
3175
3176int
Howard Hinnantc9834542011-05-31 15:34:58 +00003177__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003178{
3179 if (_Mode_ & consume_header)
3180 return 6;
3181 return 3;
3182}
3183
3184// __codecvt_utf8<char32_t>
3185
3186__codecvt_utf8<char32_t>::result
3187__codecvt_utf8<char32_t>::do_out(state_type&,
3188 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3189 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3190{
3191 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3192 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3193 const uint32_t* _frm_nxt = _frm;
3194 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3195 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3196 uint8_t* _to_nxt = _to;
3197 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3198 _Maxcode_, _Mode_);
3199 frm_nxt = frm + (_frm_nxt - _frm);
3200 to_nxt = to + (_to_nxt - _to);
3201 return r;
3202}
3203
3204__codecvt_utf8<char32_t>::result
3205__codecvt_utf8<char32_t>::do_in(state_type&,
3206 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3207 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3208{
3209 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3210 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3211 const uint8_t* _frm_nxt = _frm;
3212 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3213 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3214 uint32_t* _to_nxt = _to;
3215 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3216 _Maxcode_, _Mode_);
3217 frm_nxt = frm + (_frm_nxt - _frm);
3218 to_nxt = to + (_to_nxt - _to);
3219 return r;
3220}
3221
3222__codecvt_utf8<char32_t>::result
3223__codecvt_utf8<char32_t>::do_unshift(state_type&,
3224 extern_type* to, extern_type*, extern_type*& to_nxt) const
3225{
3226 to_nxt = to;
3227 return noconv;
3228}
3229
3230int
Howard Hinnantc9834542011-05-31 15:34:58 +00003231__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003232{
3233 return 0;
3234}
3235
3236bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003237__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003238{
3239 return false;
3240}
3241
3242int
3243__codecvt_utf8<char32_t>::do_length(state_type&,
3244 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3245{
3246 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3247 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3248 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3249}
3250
3251int
Howard Hinnantc9834542011-05-31 15:34:58 +00003252__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003253{
3254 if (_Mode_ & consume_header)
3255 return 7;
3256 return 4;
3257}
3258
3259// __codecvt_utf16<wchar_t, false>
3260
3261__codecvt_utf16<wchar_t, false>::result
3262__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3263 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3264 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3265{
3266 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3267 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3268 const uint32_t* _frm_nxt = _frm;
3269 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3270 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3271 uint8_t* _to_nxt = _to;
3272 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3273 _Maxcode_, _Mode_);
3274 frm_nxt = frm + (_frm_nxt - _frm);
3275 to_nxt = to + (_to_nxt - _to);
3276 return r;
3277}
3278
3279__codecvt_utf16<wchar_t, false>::result
3280__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3281 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3282 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3283{
3284 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3285 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3286 const uint8_t* _frm_nxt = _frm;
3287 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3288 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3289 uint32_t* _to_nxt = _to;
3290 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3291 _Maxcode_, _Mode_);
3292 frm_nxt = frm + (_frm_nxt - _frm);
3293 to_nxt = to + (_to_nxt - _to);
3294 return r;
3295}
3296
3297__codecvt_utf16<wchar_t, false>::result
3298__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3299 extern_type* to, extern_type*, extern_type*& to_nxt) const
3300{
3301 to_nxt = to;
3302 return noconv;
3303}
3304
3305int
Howard Hinnantc9834542011-05-31 15:34:58 +00003306__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003307{
3308 return 0;
3309}
3310
3311bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003312__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003313{
3314 return false;
3315}
3316
3317int
3318__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3319 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3320{
3321 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3322 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3323 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3324}
3325
3326int
Howard Hinnantc9834542011-05-31 15:34:58 +00003327__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003328{
3329 if (_Mode_ & consume_header)
3330 return 6;
3331 return 4;
3332}
3333
3334// __codecvt_utf16<wchar_t, true>
3335
3336__codecvt_utf16<wchar_t, true>::result
3337__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3338 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3339 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3340{
3341 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3342 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3343 const uint32_t* _frm_nxt = _frm;
3344 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3345 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3346 uint8_t* _to_nxt = _to;
3347 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3348 _Maxcode_, _Mode_);
3349 frm_nxt = frm + (_frm_nxt - _frm);
3350 to_nxt = to + (_to_nxt - _to);
3351 return r;
3352}
3353
3354__codecvt_utf16<wchar_t, true>::result
3355__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3356 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3357 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3358{
3359 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3360 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3361 const uint8_t* _frm_nxt = _frm;
3362 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3363 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3364 uint32_t* _to_nxt = _to;
3365 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3366 _Maxcode_, _Mode_);
3367 frm_nxt = frm + (_frm_nxt - _frm);
3368 to_nxt = to + (_to_nxt - _to);
3369 return r;
3370}
3371
3372__codecvt_utf16<wchar_t, true>::result
3373__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3374 extern_type* to, extern_type*, extern_type*& to_nxt) const
3375{
3376 to_nxt = to;
3377 return noconv;
3378}
3379
3380int
Howard Hinnantc9834542011-05-31 15:34:58 +00003381__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003382{
3383 return 0;
3384}
3385
3386bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003387__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003388{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003389 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003390}
3391
3392int
3393__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3394 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3395{
3396 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3397 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3398 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3399}
3400
3401int
Howard Hinnantc9834542011-05-31 15:34:58 +00003402__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003403{
3404 if (_Mode_ & consume_header)
3405 return 6;
3406 return 4;
3407}
3408
3409// __codecvt_utf16<char16_t, false>
3410
3411__codecvt_utf16<char16_t, false>::result
3412__codecvt_utf16<char16_t, false>::do_out(state_type&,
3413 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3414 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3415{
3416 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3417 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3418 const uint16_t* _frm_nxt = _frm;
3419 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3420 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3421 uint8_t* _to_nxt = _to;
3422 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3423 _Maxcode_, _Mode_);
3424 frm_nxt = frm + (_frm_nxt - _frm);
3425 to_nxt = to + (_to_nxt - _to);
3426 return r;
3427}
3428
3429__codecvt_utf16<char16_t, false>::result
3430__codecvt_utf16<char16_t, false>::do_in(state_type&,
3431 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3432 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3433{
3434 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3435 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3436 const uint8_t* _frm_nxt = _frm;
3437 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3438 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3439 uint16_t* _to_nxt = _to;
3440 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3441 _Maxcode_, _Mode_);
3442 frm_nxt = frm + (_frm_nxt - _frm);
3443 to_nxt = to + (_to_nxt - _to);
3444 return r;
3445}
3446
3447__codecvt_utf16<char16_t, false>::result
3448__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3449 extern_type* to, extern_type*, extern_type*& to_nxt) const
3450{
3451 to_nxt = to;
3452 return noconv;
3453}
3454
3455int
Howard Hinnantc9834542011-05-31 15:34:58 +00003456__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003457{
3458 return 0;
3459}
3460
3461bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003462__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003463{
3464 return false;
3465}
3466
3467int
3468__codecvt_utf16<char16_t, false>::do_length(state_type&,
3469 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3470{
3471 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3472 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3473 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3474}
3475
3476int
Howard Hinnantc9834542011-05-31 15:34:58 +00003477__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003478{
3479 if (_Mode_ & consume_header)
3480 return 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003481 return 2;
3482}
3483
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003484// __codecvt_utf16<char16_t, true>
3485
3486__codecvt_utf16<char16_t, true>::result
3487__codecvt_utf16<char16_t, true>::do_out(state_type&,
3488 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3489 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3490{
3491 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3492 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3493 const uint16_t* _frm_nxt = _frm;
3494 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3495 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3496 uint8_t* _to_nxt = _to;
3497 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3498 _Maxcode_, _Mode_);
3499 frm_nxt = frm + (_frm_nxt - _frm);
3500 to_nxt = to + (_to_nxt - _to);
3501 return r;
3502}
3503
3504__codecvt_utf16<char16_t, true>::result
3505__codecvt_utf16<char16_t, true>::do_in(state_type&,
3506 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3507 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3508{
3509 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3510 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3511 const uint8_t* _frm_nxt = _frm;
3512 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3513 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3514 uint16_t* _to_nxt = _to;
3515 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3516 _Maxcode_, _Mode_);
3517 frm_nxt = frm + (_frm_nxt - _frm);
3518 to_nxt = to + (_to_nxt - _to);
3519 return r;
3520}
3521
3522__codecvt_utf16<char16_t, true>::result
3523__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3524 extern_type* to, extern_type*, extern_type*& to_nxt) const
3525{
3526 to_nxt = to;
3527 return noconv;
3528}
3529
3530int
Howard Hinnantc9834542011-05-31 15:34:58 +00003531__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003532{
3533 return 0;
3534}
3535
3536bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003537__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003538{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003539 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003540}
3541
3542int
3543__codecvt_utf16<char16_t, true>::do_length(state_type&,
3544 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3545{
3546 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3547 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3548 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3549}
3550
3551int
Howard Hinnantc9834542011-05-31 15:34:58 +00003552__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003553{
3554 if (_Mode_ & consume_header)
3555 return 4;
3556 return 2;
3557}
3558
3559// __codecvt_utf16<char32_t, false>
3560
3561__codecvt_utf16<char32_t, false>::result
3562__codecvt_utf16<char32_t, false>::do_out(state_type&,
3563 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3564 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3565{
3566 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3567 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3568 const uint32_t* _frm_nxt = _frm;
3569 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3570 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3571 uint8_t* _to_nxt = _to;
3572 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3573 _Maxcode_, _Mode_);
3574 frm_nxt = frm + (_frm_nxt - _frm);
3575 to_nxt = to + (_to_nxt - _to);
3576 return r;
3577}
3578
3579__codecvt_utf16<char32_t, false>::result
3580__codecvt_utf16<char32_t, false>::do_in(state_type&,
3581 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3582 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3583{
3584 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3585 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3586 const uint8_t* _frm_nxt = _frm;
3587 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3588 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3589 uint32_t* _to_nxt = _to;
3590 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3591 _Maxcode_, _Mode_);
3592 frm_nxt = frm + (_frm_nxt - _frm);
3593 to_nxt = to + (_to_nxt - _to);
3594 return r;
3595}
3596
3597__codecvt_utf16<char32_t, false>::result
3598__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3599 extern_type* to, extern_type*, extern_type*& to_nxt) const
3600{
3601 to_nxt = to;
3602 return noconv;
3603}
3604
3605int
Howard Hinnantc9834542011-05-31 15:34:58 +00003606__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003607{
3608 return 0;
3609}
3610
3611bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003612__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003613{
3614 return false;
3615}
3616
3617int
3618__codecvt_utf16<char32_t, false>::do_length(state_type&,
3619 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3620{
3621 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3622 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3623 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3624}
3625
3626int
Howard Hinnantc9834542011-05-31 15:34:58 +00003627__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003628{
3629 if (_Mode_ & consume_header)
3630 return 6;
3631 return 4;
3632}
3633
3634// __codecvt_utf16<char32_t, true>
3635
3636__codecvt_utf16<char32_t, true>::result
3637__codecvt_utf16<char32_t, true>::do_out(state_type&,
3638 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3639 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3640{
3641 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3642 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3643 const uint32_t* _frm_nxt = _frm;
3644 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3645 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3646 uint8_t* _to_nxt = _to;
3647 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3648 _Maxcode_, _Mode_);
3649 frm_nxt = frm + (_frm_nxt - _frm);
3650 to_nxt = to + (_to_nxt - _to);
3651 return r;
3652}
3653
3654__codecvt_utf16<char32_t, true>::result
3655__codecvt_utf16<char32_t, true>::do_in(state_type&,
3656 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3657 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3658{
3659 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3660 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3661 const uint8_t* _frm_nxt = _frm;
3662 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3663 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3664 uint32_t* _to_nxt = _to;
3665 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3666 _Maxcode_, _Mode_);
3667 frm_nxt = frm + (_frm_nxt - _frm);
3668 to_nxt = to + (_to_nxt - _to);
3669 return r;
3670}
3671
3672__codecvt_utf16<char32_t, true>::result
3673__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3674 extern_type* to, extern_type*, extern_type*& to_nxt) const
3675{
3676 to_nxt = to;
3677 return noconv;
3678}
3679
3680int
Howard Hinnantc9834542011-05-31 15:34:58 +00003681__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003682{
3683 return 0;
3684}
3685
3686bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003687__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003688{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003689 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003690}
3691
3692int
3693__codecvt_utf16<char32_t, true>::do_length(state_type&,
3694 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3695{
3696 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3697 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3698 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3699}
3700
3701int
Howard Hinnantc9834542011-05-31 15:34:58 +00003702__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003703{
3704 if (_Mode_ & consume_header)
3705 return 6;
3706 return 4;
3707}
3708
3709// __codecvt_utf8_utf16<wchar_t>
3710
3711__codecvt_utf8_utf16<wchar_t>::result
3712__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3713 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3714 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3715{
3716 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3717 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3718 const uint32_t* _frm_nxt = _frm;
3719 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3720 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3721 uint8_t* _to_nxt = _to;
3722 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3723 _Maxcode_, _Mode_);
3724 frm_nxt = frm + (_frm_nxt - _frm);
3725 to_nxt = to + (_to_nxt - _to);
3726 return r;
3727}
3728
3729__codecvt_utf8_utf16<wchar_t>::result
3730__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3731 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3732 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3733{
3734 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3735 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3736 const uint8_t* _frm_nxt = _frm;
3737 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3738 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3739 uint32_t* _to_nxt = _to;
3740 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3741 _Maxcode_, _Mode_);
3742 frm_nxt = frm + (_frm_nxt - _frm);
3743 to_nxt = to + (_to_nxt - _to);
3744 return r;
3745}
3746
3747__codecvt_utf8_utf16<wchar_t>::result
3748__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3749 extern_type* to, extern_type*, extern_type*& to_nxt) const
3750{
3751 to_nxt = to;
3752 return noconv;
3753}
3754
3755int
Howard Hinnantc9834542011-05-31 15:34:58 +00003756__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003757{
3758 return 0;
3759}
3760
3761bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003762__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003763{
3764 return false;
3765}
3766
3767int
3768__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3769 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3770{
3771 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3772 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3773 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3774}
3775
3776int
Howard Hinnantc9834542011-05-31 15:34:58 +00003777__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003778{
3779 if (_Mode_ & consume_header)
3780 return 7;
3781 return 4;
3782}
3783
3784// __codecvt_utf8_utf16<char16_t>
3785
3786__codecvt_utf8_utf16<char16_t>::result
3787__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3788 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3789 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3790{
3791 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3792 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3793 const uint16_t* _frm_nxt = _frm;
3794 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3795 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3796 uint8_t* _to_nxt = _to;
3797 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3798 _Maxcode_, _Mode_);
3799 frm_nxt = frm + (_frm_nxt - _frm);
3800 to_nxt = to + (_to_nxt - _to);
3801 return r;
3802}
3803
3804__codecvt_utf8_utf16<char16_t>::result
3805__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3806 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3807 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3808{
3809 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3810 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3811 const uint8_t* _frm_nxt = _frm;
3812 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3813 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3814 uint16_t* _to_nxt = _to;
3815 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3816 _Maxcode_, _Mode_);
3817 frm_nxt = frm + (_frm_nxt - _frm);
3818 to_nxt = to + (_to_nxt - _to);
3819 return r;
3820}
3821
3822__codecvt_utf8_utf16<char16_t>::result
3823__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3824 extern_type* to, extern_type*, extern_type*& to_nxt) const
3825{
3826 to_nxt = to;
3827 return noconv;
3828}
3829
3830int
Howard Hinnantc9834542011-05-31 15:34:58 +00003831__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003832{
3833 return 0;
3834}
3835
3836bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003837__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003838{
3839 return false;
3840}
3841
3842int
3843__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3844 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3845{
3846 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3847 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3848 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3849}
3850
3851int
Howard Hinnantc9834542011-05-31 15:34:58 +00003852__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003853{
3854 if (_Mode_ & consume_header)
3855 return 7;
3856 return 4;
3857}
3858
3859// __codecvt_utf8_utf16<char32_t>
3860
3861__codecvt_utf8_utf16<char32_t>::result
3862__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3863 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3864 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3865{
3866 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3867 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3868 const uint32_t* _frm_nxt = _frm;
3869 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3870 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3871 uint8_t* _to_nxt = _to;
3872 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3873 _Maxcode_, _Mode_);
3874 frm_nxt = frm + (_frm_nxt - _frm);
3875 to_nxt = to + (_to_nxt - _to);
3876 return r;
3877}
3878
3879__codecvt_utf8_utf16<char32_t>::result
3880__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3881 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3882 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3883{
3884 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3885 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3886 const uint8_t* _frm_nxt = _frm;
3887 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3888 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3889 uint32_t* _to_nxt = _to;
3890 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3891 _Maxcode_, _Mode_);
3892 frm_nxt = frm + (_frm_nxt - _frm);
3893 to_nxt = to + (_to_nxt - _to);
3894 return r;
3895}
3896
3897__codecvt_utf8_utf16<char32_t>::result
3898__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3899 extern_type* to, extern_type*, extern_type*& to_nxt) const
3900{
3901 to_nxt = to;
3902 return noconv;
3903}
3904
3905int
Howard Hinnantc9834542011-05-31 15:34:58 +00003906__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003907{
3908 return 0;
3909}
3910
3911bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003912__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003913{
3914 return false;
3915}
3916
3917int
3918__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3919 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3920{
3921 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3922 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3923 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3924}
3925
3926int
Howard Hinnantc9834542011-05-31 15:34:58 +00003927__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003928{
3929 if (_Mode_ & consume_header)
3930 return 7;
3931 return 4;
3932}
3933
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003934// __narrow_to_utf8<16>
3935
3936__narrow_to_utf8<16>::~__narrow_to_utf8()
3937{
3938}
3939
3940// __narrow_to_utf8<32>
3941
3942__narrow_to_utf8<32>::~__narrow_to_utf8()
3943{
3944}
3945
3946// __widen_from_utf8<16>
3947
3948__widen_from_utf8<16>::~__widen_from_utf8()
3949{
3950}
3951
3952// __widen_from_utf8<32>
3953
3954__widen_from_utf8<32>::~__widen_from_utf8()
3955{
3956}
3957
3958// numpunct<char> && numpunct<wchar_t>
3959
3960locale::id numpunct< char >::id;
3961locale::id numpunct<wchar_t>::id;
3962
3963numpunct<char>::numpunct(size_t refs)
3964 : locale::facet(refs),
3965 __decimal_point_('.'),
3966 __thousands_sep_(',')
3967{
3968}
3969
3970numpunct<wchar_t>::numpunct(size_t refs)
3971 : locale::facet(refs),
3972 __decimal_point_(L'.'),
3973 __thousands_sep_(L',')
3974{
3975}
3976
3977numpunct<char>::~numpunct()
3978{
3979}
3980
3981numpunct<wchar_t>::~numpunct()
3982{
3983}
3984
3985 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
3986wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
3987
3988 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
3989wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
3990
3991string numpunct< char >::do_grouping() const {return __grouping_;}
3992string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
3993
3994 string numpunct< char >::do_truename() const {return "true";}
3995wstring numpunct<wchar_t>::do_truename() const {return L"true";}
3996
3997 string numpunct< char >::do_falsename() const {return "false";}
3998wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
3999
4000// numpunct_byname<char>
4001
4002numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4003 : numpunct<char>(refs)
4004{
4005 __init(nm);
4006}
4007
4008numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4009 : numpunct<char>(refs)
4010{
4011 __init(nm.c_str());
4012}
4013
4014numpunct_byname<char>::~numpunct_byname()
4015{
4016}
4017
4018void
4019numpunct_byname<char>::__init(const char* nm)
4020{
4021 if (strcmp(nm, "C") != 0)
4022 {
Howard Hinnantd318d492011-06-30 14:21:55 +00004023 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004024#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004025 if (loc == 0)
4026 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4027 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004028#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00004029 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004030 if (*lc->decimal_point)
4031 __decimal_point_ = *lc->decimal_point;
4032 if (*lc->thousands_sep)
4033 __thousands_sep_ = *lc->thousands_sep;
4034 __grouping_ = lc->grouping;
Sean Huntcb05a082011-07-07 22:45:07 +00004035 // localization for truename and falsename is not available
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004036 }
4037}
4038
4039// numpunct_byname<wchar_t>
4040
4041numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4042 : numpunct<wchar_t>(refs)
4043{
4044 __init(nm);
4045}
4046
4047numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4048 : numpunct<wchar_t>(refs)
4049{
4050 __init(nm.c_str());
4051}
4052
4053numpunct_byname<wchar_t>::~numpunct_byname()
4054{
4055}
4056
4057void
4058numpunct_byname<wchar_t>::__init(const char* nm)
4059{
4060 if (strcmp(nm, "C") != 0)
4061 {
Howard Hinnantd318d492011-06-30 14:21:55 +00004062 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004063#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004064 if (loc == 0)
4065 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4066 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004067#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00004068 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004069 if (*lc->decimal_point)
4070 __decimal_point_ = *lc->decimal_point;
4071 if (*lc->thousands_sep)
4072 __thousands_sep_ = *lc->thousands_sep;
4073 __grouping_ = lc->grouping;
4074 // locallization for truename and falsename is not available
4075 }
4076}
4077
4078// num_get helpers
4079
4080int
4081__num_get_base::__get_base(ios_base& iob)
4082{
4083 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4084 if (__basefield == ios_base::oct)
4085 return 8;
4086 else if (__basefield == ios_base::hex)
4087 return 16;
4088 else if (__basefield == 0)
4089 return 0;
4090 return 10;
4091}
4092
4093const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4094
4095void
4096__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4097 ios_base::iostate& __err)
4098{
4099 if (__grouping.size() != 0)
4100 {
4101 reverse(__g, __g_end);
4102 const char* __ig = __grouping.data();
4103 const char* __eg = __ig + __grouping.size();
4104 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4105 {
4106 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4107 {
4108 if (*__ig != *__r)
4109 {
4110 __err = ios_base::failbit;
4111 return;
4112 }
4113 }
4114 if (__eg - __ig > 1)
4115 ++__ig;
4116 }
4117 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4118 {
4119 if (*__ig < __g_end[-1] || __g_end[-1] == 0)
4120 __err = ios_base::failbit;
4121 }
4122 }
4123}
4124
4125void
4126__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4127 ios_base::fmtflags __flags)
4128{
4129 if (__flags & ios_base::showpos)
4130 *__fmtp++ = '+';
4131 if (__flags & ios_base::showbase)
4132 *__fmtp++ = '#';
4133 while(*__len)
4134 *__fmtp++ = *__len++;
4135 if ((__flags & ios_base::basefield) == ios_base::oct)
4136 *__fmtp = 'o';
4137 else if ((__flags & ios_base::basefield) == ios_base::hex)
4138 {
4139 if (__flags & ios_base::uppercase)
4140 *__fmtp = 'X';
4141 else
4142 *__fmtp = 'x';
4143 }
4144 else if (__signd)
4145 *__fmtp = 'd';
4146 else
4147 *__fmtp = 'u';
4148}
4149
4150bool
4151__num_put_base::__format_float(char* __fmtp, const char* __len,
4152 ios_base::fmtflags __flags)
4153{
4154 bool specify_precision = true;
4155 if (__flags & ios_base::showpos)
4156 *__fmtp++ = '+';
4157 if (__flags & ios_base::showpoint)
4158 *__fmtp++ = '#';
4159 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4160 bool uppercase = __flags & ios_base::uppercase;
4161 if (floatfield == (ios_base::fixed | ios_base::scientific))
4162 specify_precision = false;
4163 else
4164 {
4165 *__fmtp++ = '.';
4166 *__fmtp++ = '*';
4167 }
4168 while(*__len)
4169 *__fmtp++ = *__len++;
4170 if (floatfield == ios_base::fixed)
4171 {
4172 if (uppercase)
4173 *__fmtp = 'F';
4174 else
4175 *__fmtp = 'f';
4176 }
4177 else if (floatfield == ios_base::scientific)
4178 {
4179 if (uppercase)
4180 *__fmtp = 'E';
4181 else
4182 *__fmtp = 'e';
4183 }
4184 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4185 {
4186 if (uppercase)
4187 *__fmtp = 'A';
4188 else
4189 *__fmtp = 'a';
4190 }
4191 else
4192 {
4193 if (uppercase)
4194 *__fmtp = 'G';
4195 else
4196 *__fmtp = 'g';
4197 }
4198 return specify_precision;
4199}
4200
4201char*
4202__num_put_base::__identify_padding(char* __nb, char* __ne,
4203 const ios_base& __iob)
4204{
4205 switch (__iob.flags() & ios_base::adjustfield)
4206 {
4207 case ios_base::internal:
4208 if (__nb[0] == '-' || __nb[0] == '+')
4209 return __nb+1;
4210 if (__ne - __nb >= 2 && __nb[0] == '0'
4211 && (__nb[1] == 'x' || __nb[1] == 'X'))
4212 return __nb+2;
4213 break;
4214 case ios_base::left:
4215 return __ne;
4216 case ios_base::right:
4217 default:
4218 break;
4219 }
4220 return __nb;
4221}
4222
4223// time_get
4224
4225static
4226string*
4227init_weeks()
4228{
4229 static string weeks[14];
4230 weeks[0] = "Sunday";
4231 weeks[1] = "Monday";
4232 weeks[2] = "Tuesday";
4233 weeks[3] = "Wednesday";
4234 weeks[4] = "Thursday";
4235 weeks[5] = "Friday";
4236 weeks[6] = "Saturday";
4237 weeks[7] = "Sun";
4238 weeks[8] = "Mon";
4239 weeks[9] = "Tue";
4240 weeks[10] = "Wed";
4241 weeks[11] = "Thu";
4242 weeks[12] = "Fri";
4243 weeks[13] = "Sat";
4244 return weeks;
4245}
4246
4247static
4248wstring*
4249init_wweeks()
4250{
4251 static wstring weeks[14];
4252 weeks[0] = L"Sunday";
4253 weeks[1] = L"Monday";
4254 weeks[2] = L"Tuesday";
4255 weeks[3] = L"Wednesday";
4256 weeks[4] = L"Thursday";
4257 weeks[5] = L"Friday";
4258 weeks[6] = L"Saturday";
4259 weeks[7] = L"Sun";
4260 weeks[8] = L"Mon";
4261 weeks[9] = L"Tue";
4262 weeks[10] = L"Wed";
4263 weeks[11] = L"Thu";
4264 weeks[12] = L"Fri";
4265 weeks[13] = L"Sat";
4266 return weeks;
4267}
4268
4269template <>
4270const string*
4271__time_get_c_storage<char>::__weeks() const
4272{
4273 static const string* weeks = init_weeks();
4274 return weeks;
4275}
4276
4277template <>
4278const wstring*
4279__time_get_c_storage<wchar_t>::__weeks() const
4280{
4281 static const wstring* weeks = init_wweeks();
4282 return weeks;
4283}
4284
4285static
4286string*
4287init_months()
4288{
4289 static string months[24];
4290 months[0] = "January";
4291 months[1] = "February";
4292 months[2] = "March";
4293 months[3] = "April";
4294 months[4] = "May";
4295 months[5] = "June";
4296 months[6] = "July";
4297 months[7] = "August";
4298 months[8] = "September";
4299 months[9] = "October";
4300 months[10] = "November";
4301 months[11] = "December";
4302 months[12] = "Jan";
4303 months[13] = "Feb";
4304 months[14] = "Mar";
4305 months[15] = "Apr";
4306 months[16] = "May";
4307 months[17] = "Jun";
4308 months[18] = "Jul";
4309 months[19] = "Aug";
4310 months[20] = "Sep";
4311 months[21] = "Oct";
4312 months[22] = "Nov";
4313 months[23] = "Dec";
4314 return months;
4315}
4316
4317static
4318wstring*
4319init_wmonths()
4320{
4321 static wstring months[24];
4322 months[0] = L"January";
4323 months[1] = L"February";
4324 months[2] = L"March";
4325 months[3] = L"April";
4326 months[4] = L"May";
4327 months[5] = L"June";
4328 months[6] = L"July";
4329 months[7] = L"August";
4330 months[8] = L"September";
4331 months[9] = L"October";
4332 months[10] = L"November";
4333 months[11] = L"December";
4334 months[12] = L"Jan";
4335 months[13] = L"Feb";
4336 months[14] = L"Mar";
4337 months[15] = L"Apr";
4338 months[16] = L"May";
4339 months[17] = L"Jun";
4340 months[18] = L"Jul";
4341 months[19] = L"Aug";
4342 months[20] = L"Sep";
4343 months[21] = L"Oct";
4344 months[22] = L"Nov";
4345 months[23] = L"Dec";
4346 return months;
4347}
4348
4349template <>
4350const string*
4351__time_get_c_storage<char>::__months() const
4352{
4353 static const string* months = init_months();
4354 return months;
4355}
4356
4357template <>
4358const wstring*
4359__time_get_c_storage<wchar_t>::__months() const
4360{
4361 static const wstring* months = init_wmonths();
4362 return months;
4363}
4364
4365static
4366string*
4367init_am_pm()
4368{
4369 static string am_pm[24];
4370 am_pm[0] = "AM";
4371 am_pm[1] = "PM";
4372 return am_pm;
4373}
4374
4375static
4376wstring*
4377init_wam_pm()
4378{
4379 static wstring am_pm[24];
4380 am_pm[0] = L"AM";
4381 am_pm[1] = L"PM";
4382 return am_pm;
4383}
4384
4385template <>
4386const string*
4387__time_get_c_storage<char>::__am_pm() const
4388{
4389 static const string* am_pm = init_am_pm();
4390 return am_pm;
4391}
4392
4393template <>
4394const wstring*
4395__time_get_c_storage<wchar_t>::__am_pm() const
4396{
4397 static const wstring* am_pm = init_wam_pm();
4398 return am_pm;
4399}
4400
4401template <>
4402const string&
4403__time_get_c_storage<char>::__x() const
4404{
4405 static string s("%m/%d/%y");
4406 return s;
4407}
4408
4409template <>
4410const wstring&
4411__time_get_c_storage<wchar_t>::__x() const
4412{
4413 static wstring s(L"%m/%d/%y");
4414 return s;
4415}
4416
4417template <>
4418const string&
4419__time_get_c_storage<char>::__X() const
4420{
4421 static string s("%H:%M:%S");
4422 return s;
4423}
4424
4425template <>
4426const wstring&
4427__time_get_c_storage<wchar_t>::__X() const
4428{
4429 static wstring s(L"%H:%M:%S");
4430 return s;
4431}
4432
4433template <>
4434const string&
4435__time_get_c_storage<char>::__c() const
4436{
4437 static string s("%a %b %d %H:%M:%S %Y");
4438 return s;
4439}
4440
4441template <>
4442const wstring&
4443__time_get_c_storage<wchar_t>::__c() const
4444{
4445 static wstring s(L"%a %b %d %H:%M:%S %Y");
4446 return s;
4447}
4448
4449template <>
4450const string&
4451__time_get_c_storage<char>::__r() const
4452{
4453 static string s("%I:%M:%S %p");
4454 return s;
4455}
4456
4457template <>
4458const wstring&
4459__time_get_c_storage<wchar_t>::__r() const
4460{
4461 static wstring s(L"%I:%M:%S %p");
4462 return s;
4463}
4464
4465// time_get_byname
4466
4467__time_get::__time_get(const char* nm)
4468 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4469{
Howard Hinnantd4444702010-08-11 17:04:31 +00004470#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004471 if (__loc_ == 0)
4472 throw runtime_error("time_get_byname"
4473 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004474#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004475}
4476
4477__time_get::__time_get(const string& nm)
4478 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4479{
Howard Hinnantd4444702010-08-11 17:04:31 +00004480#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004481 if (__loc_ == 0)
4482 throw runtime_error("time_get_byname"
4483 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004484#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004485}
4486
4487__time_get::~__time_get()
4488{
4489 freelocale(__loc_);
4490}
4491
4492template <>
4493string
4494__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4495{
4496 tm t;
4497 t.tm_sec = 59;
4498 t.tm_min = 55;
4499 t.tm_hour = 23;
4500 t.tm_mday = 31;
4501 t.tm_mon = 11;
4502 t.tm_year = 161;
4503 t.tm_wday = 6;
4504 t.tm_yday = 364;
4505 t.tm_isdst = -1;
4506 char buf[100];
4507 char f[3] = {0};
4508 f[0] = '%';
4509 f[1] = fmt;
4510 size_t n = strftime_l(buf, 100, f, &t, __loc_);
4511 char* bb = buf;
4512 char* be = buf + n;
4513 string result;
4514 while (bb != be)
4515 {
4516 if (ct.is(ctype_base::space, *bb))
4517 {
4518 result.push_back(' ');
4519 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4520 ;
4521 continue;
4522 }
4523 char* w = bb;
4524 ios_base::iostate err = ios_base::goodbit;
4525 int i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4526 ct, err, false)
4527 - this->__weeks_;
4528 if (i < 14)
4529 {
4530 result.push_back('%');
4531 if (i < 7)
4532 result.push_back('A');
4533 else
4534 result.push_back('a');
4535 bb = w;
4536 continue;
4537 }
4538 w = bb;
4539 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4540 ct, err, false)
4541 - this->__months_;
4542 if (i < 24)
4543 {
4544 result.push_back('%');
4545 if (i < 12)
4546 result.push_back('B');
4547 else
4548 result.push_back('b');
4549 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4550 result.back() = 'm';
4551 bb = w;
4552 continue;
4553 }
4554 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4555 {
4556 w = bb;
4557 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4558 ct, err, false) - this->__am_pm_;
4559 if (i < 2)
4560 {
4561 result.push_back('%');
4562 result.push_back('p');
4563 bb = w;
4564 continue;
4565 }
4566 }
4567 w = bb;
4568 if (ct.is(ctype_base::digit, *bb))
4569 {
4570 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4571 {
4572 case 6:
4573 result.push_back('%');
4574 result.push_back('w');
4575 break;
4576 case 7:
4577 result.push_back('%');
4578 result.push_back('u');
4579 break;
4580 case 11:
4581 result.push_back('%');
4582 result.push_back('I');
4583 break;
4584 case 12:
4585 result.push_back('%');
4586 result.push_back('m');
4587 break;
4588 case 23:
4589 result.push_back('%');
4590 result.push_back('H');
4591 break;
4592 case 31:
4593 result.push_back('%');
4594 result.push_back('d');
4595 break;
4596 case 55:
4597 result.push_back('%');
4598 result.push_back('M');
4599 break;
4600 case 59:
4601 result.push_back('%');
4602 result.push_back('S');
4603 break;
4604 case 61:
4605 result.push_back('%');
4606 result.push_back('y');
4607 break;
4608 case 364:
4609 result.push_back('%');
4610 result.push_back('j');
4611 break;
4612 case 2061:
4613 result.push_back('%');
4614 result.push_back('Y');
4615 break;
4616 default:
4617 for (; w != bb; ++w)
4618 result.push_back(*w);
4619 break;
4620 }
4621 continue;
4622 }
4623 if (*bb == '%')
4624 {
4625 result.push_back('%');
4626 result.push_back('%');
4627 ++bb;
4628 continue;
4629 }
4630 result.push_back(*bb);
4631 ++bb;
4632 }
4633 return result;
4634}
4635
4636template <>
4637wstring
4638__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4639{
4640 tm t;
4641 t.tm_sec = 59;
4642 t.tm_min = 55;
4643 t.tm_hour = 23;
4644 t.tm_mday = 31;
4645 t.tm_mon = 11;
4646 t.tm_year = 161;
4647 t.tm_wday = 6;
4648 t.tm_yday = 364;
4649 t.tm_isdst = -1;
4650 char buf[100];
4651 char f[3] = {0};
4652 f[0] = '%';
4653 f[1] = fmt;
4654 size_t be = strftime_l(buf, 100, f, &t, __loc_);
4655 wchar_t wbuf[100];
4656 wchar_t* wbb = wbuf;
4657 mbstate_t mb = {0};
4658 const char* bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004659 size_t i = with_locale::mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004660 if (i == -1)
4661 __throw_runtime_error("locale not supported");
4662 wchar_t* wbe = wbb + i;
4663 wstring result;
4664 while (wbb != wbe)
4665 {
4666 if (ct.is(ctype_base::space, *wbb))
4667 {
4668 result.push_back(L' ');
4669 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4670 ;
4671 continue;
4672 }
4673 wchar_t* w = wbb;
4674 ios_base::iostate err = ios_base::goodbit;
4675 int i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4676 ct, err, false)
4677 - this->__weeks_;
4678 if (i < 14)
4679 {
4680 result.push_back(L'%');
4681 if (i < 7)
4682 result.push_back(L'A');
4683 else
4684 result.push_back(L'a');
4685 wbb = w;
4686 continue;
4687 }
4688 w = wbb;
4689 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4690 ct, err, false)
4691 - this->__months_;
4692 if (i < 24)
4693 {
4694 result.push_back(L'%');
4695 if (i < 12)
4696 result.push_back(L'B');
4697 else
4698 result.push_back(L'b');
4699 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4700 result.back() = L'm';
4701 wbb = w;
4702 continue;
4703 }
4704 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4705 {
4706 w = wbb;
4707 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4708 ct, err, false) - this->__am_pm_;
4709 if (i < 2)
4710 {
4711 result.push_back(L'%');
4712 result.push_back(L'p');
4713 wbb = w;
4714 continue;
4715 }
4716 }
4717 w = wbb;
4718 if (ct.is(ctype_base::digit, *wbb))
4719 {
4720 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4721 {
4722 case 6:
4723 result.push_back(L'%');
4724 result.push_back(L'w');
4725 break;
4726 case 7:
4727 result.push_back(L'%');
4728 result.push_back(L'u');
4729 break;
4730 case 11:
4731 result.push_back(L'%');
4732 result.push_back(L'I');
4733 break;
4734 case 12:
4735 result.push_back(L'%');
4736 result.push_back(L'm');
4737 break;
4738 case 23:
4739 result.push_back(L'%');
4740 result.push_back(L'H');
4741 break;
4742 case 31:
4743 result.push_back(L'%');
4744 result.push_back(L'd');
4745 break;
4746 case 55:
4747 result.push_back(L'%');
4748 result.push_back(L'M');
4749 break;
4750 case 59:
4751 result.push_back(L'%');
4752 result.push_back(L'S');
4753 break;
4754 case 61:
4755 result.push_back(L'%');
4756 result.push_back(L'y');
4757 break;
4758 case 364:
4759 result.push_back(L'%');
4760 result.push_back(L'j');
4761 break;
4762 case 2061:
4763 result.push_back(L'%');
4764 result.push_back(L'Y');
4765 break;
4766 default:
4767 for (; w != wbb; ++w)
4768 result.push_back(*w);
4769 break;
4770 }
4771 continue;
4772 }
4773 if (ct.narrow(*wbb, 0) == '%')
4774 {
4775 result.push_back(L'%');
4776 result.push_back(L'%');
4777 ++wbb;
4778 continue;
4779 }
4780 result.push_back(*wbb);
4781 ++wbb;
4782 }
4783 return result;
4784}
4785
4786template <>
4787void
4788__time_get_storage<char>::init(const ctype<char>& ct)
4789{
4790 tm t;
4791 char buf[100];
4792 // __weeks_
4793 for (int i = 0; i < 7; ++i)
4794 {
4795 t.tm_wday = i;
4796 strftime_l(buf, 100, "%A", &t, __loc_);
4797 __weeks_[i] = buf;
4798 strftime_l(buf, 100, "%a", &t, __loc_);
4799 __weeks_[i+7] = buf;
4800 }
4801 // __months_
4802 for (int i = 0; i < 12; ++i)
4803 {
4804 t.tm_mon = i;
4805 strftime_l(buf, 100, "%B", &t, __loc_);
4806 __months_[i] = buf;
4807 strftime_l(buf, 100, "%b", &t, __loc_);
4808 __months_[i+12] = buf;
4809 }
4810 // __am_pm_
4811 t.tm_hour = 1;
4812 strftime_l(buf, 100, "%p", &t, __loc_);
4813 __am_pm_[0] = buf;
4814 t.tm_hour = 13;
4815 strftime_l(buf, 100, "%p", &t, __loc_);
4816 __am_pm_[1] = buf;
4817 __c_ = __analyze('c', ct);
4818 __r_ = __analyze('r', ct);
4819 __x_ = __analyze('x', ct);
4820 __X_ = __analyze('X', ct);
4821}
4822
4823template <>
4824void
4825__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4826{
4827 tm t = {0};
4828 char buf[100];
4829 size_t be;
4830 wchar_t wbuf[100];
4831 wchar_t* wbe;
4832 mbstate_t mb = {0};
4833 // __weeks_
4834 for (int i = 0; i < 7; ++i)
4835 {
4836 t.tm_wday = i;
4837 be = strftime_l(buf, 100, "%A", &t, __loc_);
4838 mb = mbstate_t();
4839 const char* bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004840 size_t j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004841 if (j == -1)
4842 __throw_runtime_error("locale not supported");
4843 wbe = wbuf + j;
4844 __weeks_[i].assign(wbuf, wbe);
4845 be = strftime_l(buf, 100, "%a", &t, __loc_);
4846 mb = mbstate_t();
4847 bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004848 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004849 if (j == -1)
4850 __throw_runtime_error("locale not supported");
4851 wbe = wbuf + j;
4852 __weeks_[i+7].assign(wbuf, wbe);
4853 }
4854 // __months_
4855 for (int i = 0; i < 12; ++i)
4856 {
4857 t.tm_mon = i;
4858 be = strftime_l(buf, 100, "%B", &t, __loc_);
4859 mb = mbstate_t();
4860 const char* bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004861 size_t j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004862 if (j == -1)
4863 __throw_runtime_error("locale not supported");
4864 wbe = wbuf + j;
4865 __months_[i].assign(wbuf, wbe);
4866 be = strftime_l(buf, 100, "%b", &t, __loc_);
4867 mb = mbstate_t();
4868 bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004869 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004870 if (j == -1)
4871 __throw_runtime_error("locale not supported");
4872 wbe = wbuf + j;
4873 __months_[i+12].assign(wbuf, wbe);
4874 }
4875 // __am_pm_
4876 t.tm_hour = 1;
4877 be = strftime_l(buf, 100, "%p", &t, __loc_);
4878 mb = mbstate_t();
4879 const char* bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004880 size_t j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004881 if (j == -1)
4882 __throw_runtime_error("locale not supported");
4883 wbe = wbuf + j;
4884 __am_pm_[0].assign(wbuf, wbe);
4885 t.tm_hour = 13;
4886 be = strftime_l(buf, 100, "%p", &t, __loc_);
4887 mb = mbstate_t();
4888 bb = buf;
Howard Hinnantd318d492011-06-30 14:21:55 +00004889 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004890 if (j == -1)
4891 __throw_runtime_error("locale not supported");
4892 wbe = wbuf + j;
4893 __am_pm_[1].assign(wbuf, wbe);
4894 __c_ = __analyze('c', ct);
4895 __r_ = __analyze('r', ct);
4896 __x_ = __analyze('x', ct);
4897 __X_ = __analyze('X', ct);
4898}
4899
4900template <class CharT>
4901struct _LIBCPP_HIDDEN __time_get_temp
4902 : public ctype_byname<CharT>
4903{
4904 explicit __time_get_temp(const char* nm)
4905 : ctype_byname<CharT>(nm, 1) {}
4906 explicit __time_get_temp(const string& nm)
4907 : ctype_byname<CharT>(nm, 1) {}
4908};
4909
4910template <>
4911__time_get_storage<char>::__time_get_storage(const char* __nm)
4912 : __time_get(__nm)
4913{
4914 const __time_get_temp<char> ct(__nm);
4915 init(ct);
4916}
4917
4918template <>
4919__time_get_storage<char>::__time_get_storage(const string& __nm)
4920 : __time_get(__nm)
4921{
4922 const __time_get_temp<char> ct(__nm);
4923 init(ct);
4924}
4925
4926template <>
4927__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
4928 : __time_get(__nm)
4929{
4930 const __time_get_temp<wchar_t> ct(__nm);
4931 init(ct);
4932}
4933
4934template <>
4935__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
4936 : __time_get(__nm)
4937{
4938 const __time_get_temp<wchar_t> ct(__nm);
4939 init(ct);
4940}
4941
4942template <>
4943time_base::dateorder
4944__time_get_storage<char>::__do_date_order() const
4945{
4946 unsigned i;
4947 for (i = 0; i < __x_.size(); ++i)
4948 if (__x_[i] == '%')
4949 break;
4950 ++i;
4951 switch (__x_[i])
4952 {
4953 case 'y':
4954 case 'Y':
4955 for (++i; i < __x_.size(); ++i)
4956 if (__x_[i] == '%')
4957 break;
4958 if (i == __x_.size())
4959 break;
4960 ++i;
4961 switch (__x_[i])
4962 {
4963 case 'm':
4964 for (++i; i < __x_.size(); ++i)
4965 if (__x_[i] == '%')
4966 break;
4967 if (i == __x_.size())
4968 break;
4969 ++i;
4970 if (__x_[i] == 'd')
4971 return time_base::ymd;
4972 break;
4973 case 'd':
4974 for (++i; i < __x_.size(); ++i)
4975 if (__x_[i] == '%')
4976 break;
4977 if (i == __x_.size())
4978 break;
4979 ++i;
4980 if (__x_[i] == 'm')
4981 return time_base::ydm;
4982 break;
4983 }
4984 break;
4985 case 'm':
4986 for (++i; i < __x_.size(); ++i)
4987 if (__x_[i] == '%')
4988 break;
4989 if (i == __x_.size())
4990 break;
4991 ++i;
4992 if (__x_[i] == 'd')
4993 {
4994 for (++i; i < __x_.size(); ++i)
4995 if (__x_[i] == '%')
4996 break;
4997 if (i == __x_.size())
4998 break;
4999 ++i;
5000 if (__x_[i] == 'y' || __x_[i] == 'Y')
5001 return time_base::mdy;
5002 break;
5003 }
5004 break;
5005 case 'd':
5006 for (++i; i < __x_.size(); ++i)
5007 if (__x_[i] == '%')
5008 break;
5009 if (i == __x_.size())
5010 break;
5011 ++i;
5012 if (__x_[i] == 'm')
5013 {
5014 for (++i; i < __x_.size(); ++i)
5015 if (__x_[i] == '%')
5016 break;
5017 if (i == __x_.size())
5018 break;
5019 ++i;
5020 if (__x_[i] == 'y' || __x_[i] == 'Y')
5021 return time_base::dmy;
5022 break;
5023 }
5024 break;
5025 }
5026 return time_base::no_order;
5027}
5028
5029template <>
5030time_base::dateorder
5031__time_get_storage<wchar_t>::__do_date_order() const
5032{
5033 unsigned i;
5034 for (i = 0; i < __x_.size(); ++i)
5035 if (__x_[i] == L'%')
5036 break;
5037 ++i;
5038 switch (__x_[i])
5039 {
5040 case L'y':
5041 case L'Y':
5042 for (++i; i < __x_.size(); ++i)
5043 if (__x_[i] == L'%')
5044 break;
5045 if (i == __x_.size())
5046 break;
5047 ++i;
5048 switch (__x_[i])
5049 {
5050 case L'm':
5051 for (++i; i < __x_.size(); ++i)
5052 if (__x_[i] == L'%')
5053 break;
5054 if (i == __x_.size())
5055 break;
5056 ++i;
5057 if (__x_[i] == L'd')
5058 return time_base::ymd;
5059 break;
5060 case L'd':
5061 for (++i; i < __x_.size(); ++i)
5062 if (__x_[i] == L'%')
5063 break;
5064 if (i == __x_.size())
5065 break;
5066 ++i;
5067 if (__x_[i] == L'm')
5068 return time_base::ydm;
5069 break;
5070 }
5071 break;
5072 case L'm':
5073 for (++i; i < __x_.size(); ++i)
5074 if (__x_[i] == L'%')
5075 break;
5076 if (i == __x_.size())
5077 break;
5078 ++i;
5079 if (__x_[i] == L'd')
5080 {
5081 for (++i; i < __x_.size(); ++i)
5082 if (__x_[i] == L'%')
5083 break;
5084 if (i == __x_.size())
5085 break;
5086 ++i;
5087 if (__x_[i] == L'y' || __x_[i] == L'Y')
5088 return time_base::mdy;
5089 break;
5090 }
5091 break;
5092 case L'd':
5093 for (++i; i < __x_.size(); ++i)
5094 if (__x_[i] == L'%')
5095 break;
5096 if (i == __x_.size())
5097 break;
5098 ++i;
5099 if (__x_[i] == L'm')
5100 {
5101 for (++i; i < __x_.size(); ++i)
5102 if (__x_[i] == L'%')
5103 break;
5104 if (i == __x_.size())
5105 break;
5106 ++i;
5107 if (__x_[i] == L'y' || __x_[i] == L'Y')
5108 return time_base::dmy;
5109 break;
5110 }
5111 break;
5112 }
5113 return time_base::no_order;
5114}
5115
5116// time_put
5117
5118__time_put::__time_put(const char* nm)
5119 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5120{
Howard Hinnantd4444702010-08-11 17:04:31 +00005121#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005122 if (__loc_ == 0)
5123 throw runtime_error("time_put_byname"
5124 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005125#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005126}
5127
5128__time_put::__time_put(const string& nm)
5129 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5130{
Howard Hinnantd4444702010-08-11 17:04:31 +00005131#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005132 if (__loc_ == 0)
5133 throw runtime_error("time_put_byname"
5134 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005135#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005136}
5137
5138__time_put::~__time_put()
5139{
5140 if (__loc_)
5141 freelocale(__loc_);
5142}
5143
5144void
5145__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5146 char __fmt, char __mod) const
5147{
5148 char fmt[] = {'%', __fmt, __mod, 0};
5149 if (__mod != 0)
5150 swap(fmt[1], fmt[2]);
5151 size_t n = strftime_l(__nb, __ne-__nb, fmt, __tm, __loc_);
5152 __ne = __nb + n;
5153}
5154
5155void
5156__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5157 char __fmt, char __mod) const
5158{
5159 char __nar[100];
5160 char* __ne = __nar + 100;
5161 __do_put(__nar, __ne, __tm, __fmt, __mod);
5162 mbstate_t mb = {0};
5163 const char* __nb = __nar;
Howard Hinnantd318d492011-06-30 14:21:55 +00005164 size_t j = with_locale::mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005165 if (j == -1)
5166 __throw_runtime_error("locale not supported");
5167 __we = __wb + j;
5168}
5169
5170// moneypunct_byname
5171
5172static
5173void
5174__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5175{
5176 const char sign = static_cast<char>(money_base::sign);
5177 const char space = static_cast<char>(money_base::space);
5178 const char none = static_cast<char>(money_base::none);
5179 const char symbol = static_cast<char>(money_base::symbol);
5180 const char value = static_cast<char>(money_base::value);
5181 switch (cs_precedes)
5182 {
5183 case 0:
5184 switch (sign_posn)
5185 {
5186 case 0:
5187 pat.field[0] = sign;
5188 pat.field[1] = value;
5189 pat.field[3] = symbol;
5190 switch (sep_by_space)
5191 {
5192 case 0:
5193 pat.field[2] = none;
5194 return;
5195 case 1:
5196 case 2:
5197 pat.field[2] = space;
5198 return;
5199 default:
5200 break;
5201 }
5202 break;
5203 case 1:
5204 pat.field[0] = sign;
5205 pat.field[3] = symbol;
5206 switch (sep_by_space)
5207 {
5208 case 0:
5209 pat.field[1] = value;
5210 pat.field[2] = none;
5211 return;
5212 case 1:
5213 pat.field[1] = value;
5214 pat.field[2] = space;
5215 return;
5216 case 2:
5217 pat.field[1] = space;
5218 pat.field[2] = value;
5219 return;
5220 default:
5221 break;
5222 }
5223 break;
5224 case 2:
5225 pat.field[0] = value;
5226 pat.field[3] = sign;
5227 switch (sep_by_space)
5228 {
5229 case 0:
5230 pat.field[1] = none;
5231 pat.field[2] = symbol;
5232 return;
5233 case 1:
5234 pat.field[1] = space;
5235 pat.field[2] = symbol;
5236 return;
5237 case 2:
5238 pat.field[1] = symbol;
5239 pat.field[2] = space;
5240 return;
5241 default:
5242 break;
5243 }
5244 break;
5245 case 3:
5246 pat.field[0] = value;
5247 pat.field[3] = symbol;
5248 switch (sep_by_space)
5249 {
5250 case 0:
5251 pat.field[1] = none;
5252 pat.field[2] = sign;
5253 return;
5254 case 1:
5255 pat.field[1] = space;
5256 pat.field[2] = sign;
5257 return;
5258 case 2:
5259 pat.field[1] = sign;
5260 pat.field[2] = space;
5261 return;
5262 default:
5263 break;
5264 }
5265 break;
5266 case 4:
5267 pat.field[0] = value;
5268 pat.field[3] = sign;
5269 switch (sep_by_space)
5270 {
5271 case 0:
5272 pat.field[1] = none;
5273 pat.field[2] = symbol;
5274 return;
5275 case 1:
5276 pat.field[1] = space;
5277 pat.field[2] = symbol;
5278 return;
5279 case 2:
5280 pat.field[1] = symbol;
5281 pat.field[2] = space;
5282 return;
5283 default:
5284 break;
5285 }
5286 break;
5287 default:
5288 break;
5289 }
5290 break;
5291 case 1:
5292 switch (sign_posn)
5293 {
5294 case 0:
5295 pat.field[0] = sign;
5296 pat.field[1] = symbol;
5297 pat.field[3] = value;
5298 switch (sep_by_space)
5299 {
5300 case 0:
5301 pat.field[2] = none;
5302 return;
5303 case 1:
5304 case 2:
5305 pat.field[2] = space;
5306 return;
5307 default:
5308 break;
5309 }
5310 break;
5311 case 1:
5312 pat.field[0] = sign;
5313 pat.field[3] = value;
5314 switch (sep_by_space)
5315 {
5316 case 0:
5317 pat.field[1] = symbol;
5318 pat.field[2] = none;
5319 return;
5320 case 1:
5321 pat.field[1] = symbol;
5322 pat.field[2] = space;
5323 return;
5324 case 2:
5325 pat.field[1] = space;
5326 pat.field[2] = symbol;
5327 return;
5328 default:
5329 break;
5330 }
5331 break;
5332 case 2:
5333 pat.field[0] = symbol;
5334 pat.field[3] = sign;
5335 switch (sep_by_space)
5336 {
5337 case 0:
5338 pat.field[1] = none;
5339 pat.field[2] = value;
5340 return;
5341 case 1:
5342 pat.field[1] = space;
5343 pat.field[2] = value;
5344 return;
5345 case 2:
5346 pat.field[1] = value;
5347 pat.field[2] = space;
5348 return;
5349 default:
5350 break;
5351 }
5352 break;
5353 case 3:
5354 pat.field[0] = sign;
5355 pat.field[3] = value;
5356 switch (sep_by_space)
5357 {
5358 case 0:
5359 pat.field[1] = symbol;
5360 pat.field[2] = none;
5361 return;
5362 case 1:
5363 pat.field[1] = symbol;
5364 pat.field[2] = space;
5365 return;
5366 case 2:
5367 pat.field[1] = space;
5368 pat.field[2] = symbol;
5369 return;
5370 default:
5371 break;
5372 }
5373 break;
5374 case 4:
5375 pat.field[0] = symbol;
5376 pat.field[3] = value;
5377 switch (sep_by_space)
5378 {
5379 case 0:
5380 pat.field[1] = sign;
5381 pat.field[2] = none;
5382 return;
5383 case 1:
5384 pat.field[1] = sign;
5385 pat.field[2] = space;
5386 return;
5387 case 2:
5388 pat.field[1] = space;
5389 pat.field[2] = sign;
5390 return;
5391 default:
5392 break;
5393 }
5394 break;
5395 default:
5396 break;
5397 }
5398 break;
5399 default:
5400 break;
5401 }
5402 pat.field[0] = symbol;
5403 pat.field[1] = sign;
5404 pat.field[2] = none;
5405 pat.field[3] = value;
5406}
5407
5408template<>
5409void
5410moneypunct_byname<char, false>::init(const char* nm)
5411{
5412 typedef moneypunct<char, false> base;
Howard Hinnantd318d492011-06-30 14:21:55 +00005413 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005414#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005415 if (loc == 0)
5416 throw runtime_error("moneypunct_byname"
5417 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005418#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00005419 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005420 if (*lc->mon_decimal_point)
5421 __decimal_point_ = *lc->mon_decimal_point;
5422 else
5423 __decimal_point_ = base::do_decimal_point();
5424 if (*lc->mon_thousands_sep)
5425 __thousands_sep_ = *lc->mon_thousands_sep;
5426 else
5427 __thousands_sep_ = base::do_thousands_sep();
5428 __grouping_ = lc->mon_grouping;
5429 __curr_symbol_ = lc->currency_symbol;
5430 if (lc->frac_digits != CHAR_MAX)
5431 __frac_digits_ = lc->frac_digits;
5432 else
5433 __frac_digits_ = base::do_frac_digits();
5434 if (lc->p_sign_posn == 0)
5435 __positive_sign_ = "()";
5436 else
5437 __positive_sign_ = lc->positive_sign;
5438 if (lc->n_sign_posn == 0)
5439 __negative_sign_ = "()";
5440 else
5441 __negative_sign_ = lc->negative_sign;
5442 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5443 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5444}
5445
5446template<>
5447void
5448moneypunct_byname<char, true>::init(const char* nm)
5449{
5450 typedef moneypunct<char, true> base;
Howard Hinnantd318d492011-06-30 14:21:55 +00005451 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005452#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005453 if (loc == 0)
5454 throw runtime_error("moneypunct_byname"
5455 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005456#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00005457 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005458 if (*lc->mon_decimal_point)
5459 __decimal_point_ = *lc->mon_decimal_point;
5460 else
5461 __decimal_point_ = base::do_decimal_point();
5462 if (*lc->mon_thousands_sep)
5463 __thousands_sep_ = *lc->mon_thousands_sep;
5464 else
5465 __thousands_sep_ = base::do_thousands_sep();
5466 __grouping_ = lc->mon_grouping;
5467 __curr_symbol_ = lc->int_curr_symbol;
5468 if (lc->int_frac_digits != CHAR_MAX)
5469 __frac_digits_ = lc->int_frac_digits;
5470 else
5471 __frac_digits_ = base::do_frac_digits();
5472 if (lc->int_p_sign_posn == 0)
5473 __positive_sign_ = "()";
5474 else
5475 __positive_sign_ = lc->positive_sign;
5476 if (lc->int_n_sign_posn == 0)
5477 __negative_sign_ = "()";
5478 else
5479 __negative_sign_ = lc->negative_sign;
5480 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5481 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5482}
5483
5484template<>
5485void
5486moneypunct_byname<wchar_t, false>::init(const char* nm)
5487{
5488 typedef moneypunct<wchar_t, false> base;
Howard Hinnantd318d492011-06-30 14:21:55 +00005489 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005490#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005491 if (loc == 0)
5492 throw runtime_error("moneypunct_byname"
5493 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005494#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00005495 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005496 if (*lc->mon_decimal_point)
5497 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5498 else
5499 __decimal_point_ = base::do_decimal_point();
5500 if (*lc->mon_thousands_sep)
5501 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5502 else
5503 __thousands_sep_ = base::do_thousands_sep();
5504 __grouping_ = lc->mon_grouping;
5505 wchar_t wbuf[100];
5506 mbstate_t mb = {0};
5507 const char* bb = lc->currency_symbol;
Howard Hinnantd318d492011-06-30 14:21:55 +00005508 size_t j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005509 if (j == -1)
5510 __throw_runtime_error("locale not supported");
5511 wchar_t* wbe = wbuf + j;
5512 __curr_symbol_.assign(wbuf, wbe);
5513 if (lc->frac_digits != CHAR_MAX)
5514 __frac_digits_ = lc->frac_digits;
5515 else
5516 __frac_digits_ = base::do_frac_digits();
5517 if (lc->p_sign_posn == 0)
5518 __positive_sign_ = L"()";
5519 else
5520 {
5521 mb = mbstate_t();
5522 bb = lc->positive_sign;
Howard Hinnantd318d492011-06-30 14:21:55 +00005523 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005524 if (j == -1)
5525 __throw_runtime_error("locale not supported");
5526 wbe = wbuf + j;
5527 __positive_sign_.assign(wbuf, wbe);
5528 }
5529 if (lc->n_sign_posn == 0)
5530 __negative_sign_ = L"()";
5531 else
5532 {
5533 mb = mbstate_t();
5534 bb = lc->negative_sign;
Howard Hinnantd318d492011-06-30 14:21:55 +00005535 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005536 if (j == -1)
5537 __throw_runtime_error("locale not supported");
5538 wbe = wbuf + j;
5539 __negative_sign_.assign(wbuf, wbe);
5540 }
5541 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5542 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5543}
5544
5545template<>
5546void
5547moneypunct_byname<wchar_t, true>::init(const char* nm)
5548{
5549 typedef moneypunct<wchar_t, true> base;
Howard Hinnantd318d492011-06-30 14:21:55 +00005550 locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005551#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005552 if (loc == 0)
5553 throw runtime_error("moneypunct_byname"
5554 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005555#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd318d492011-06-30 14:21:55 +00005556 lconv* lc = with_locale::localeconv_l(loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005557 if (*lc->mon_decimal_point)
5558 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5559 else
5560 __decimal_point_ = base::do_decimal_point();
5561 if (*lc->mon_thousands_sep)
5562 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5563 else
5564 __thousands_sep_ = base::do_thousands_sep();
5565 __grouping_ = lc->mon_grouping;
5566 wchar_t wbuf[100];
5567 mbstate_t mb = {0};
5568 const char* bb = lc->int_curr_symbol;
Howard Hinnantd318d492011-06-30 14:21:55 +00005569 size_t j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005570 if (j == -1)
5571 __throw_runtime_error("locale not supported");
5572 wchar_t* wbe = wbuf + j;
5573 __curr_symbol_.assign(wbuf, wbe);
5574 if (lc->int_frac_digits != CHAR_MAX)
5575 __frac_digits_ = lc->int_frac_digits;
5576 else
5577 __frac_digits_ = base::do_frac_digits();
5578 if (lc->int_p_sign_posn == 0)
5579 __positive_sign_ = L"()";
5580 else
5581 {
5582 mb = mbstate_t();
5583 bb = lc->positive_sign;
Howard Hinnantd318d492011-06-30 14:21:55 +00005584 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005585 if (j == -1)
5586 __throw_runtime_error("locale not supported");
5587 wbe = wbuf + j;
5588 __positive_sign_.assign(wbuf, wbe);
5589 }
5590 if (lc->int_n_sign_posn == 0)
5591 __negative_sign_ = L"()";
5592 else
5593 {
5594 mb = mbstate_t();
5595 bb = lc->negative_sign;
Howard Hinnantd318d492011-06-30 14:21:55 +00005596 j = with_locale::mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005597 if (j == -1)
5598 __throw_runtime_error("locale not supported");
5599 wbe = wbuf + j;
5600 __negative_sign_.assign(wbuf, wbe);
5601 }
5602 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5603 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5604}
5605
5606void __do_nothing(void*) {}
5607
5608void __throw_runtime_error(const char* msg)
5609{
Howard Hinnantd4444702010-08-11 17:04:31 +00005610#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005611 throw runtime_error(msg);
Howard Hinnantd4444702010-08-11 17:04:31 +00005612#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005613}
5614
5615template class collate<char>;
5616template class collate<wchar_t>;
5617
5618template class num_get<char>;
5619template class num_get<wchar_t>;
5620
5621template class __num_get<char>;
5622template class __num_get<wchar_t>;
5623
5624template class num_put<char>;
5625template class num_put<wchar_t>;
5626
5627template class __num_put<char>;
5628template class __num_put<wchar_t>;
5629
5630template class time_get<char>;
5631template class time_get<wchar_t>;
5632
5633template class time_get_byname<char>;
5634template class time_get_byname<wchar_t>;
5635
5636template class time_put<char>;
5637template class time_put<wchar_t>;
5638
5639template class time_put_byname<char>;
5640template class time_put_byname<wchar_t>;
5641
5642template class moneypunct<char, false>;
5643template class moneypunct<char, true>;
5644template class moneypunct<wchar_t, false>;
5645template class moneypunct<wchar_t, true>;
5646
5647template class moneypunct_byname<char, false>;
5648template class moneypunct_byname<char, true>;
5649template class moneypunct_byname<wchar_t, false>;
5650template class moneypunct_byname<wchar_t, true>;
5651
5652template class money_get<char>;
5653template class money_get<wchar_t>;
5654
5655template class __money_get<char>;
5656template class __money_get<wchar_t>;
5657
5658template class money_put<char>;
5659template class money_put<wchar_t>;
5660
5661template class __money_put<char>;
5662template class __money_put<wchar_t>;
5663
5664template class messages<char>;
5665template class messages<wchar_t>;
5666
5667template class messages_byname<char>;
5668template class messages_byname<wchar_t>;
5669
5670template class codecvt_byname<char, char, mbstate_t>;
5671template class codecvt_byname<wchar_t, char, mbstate_t>;
5672template class codecvt_byname<char16_t, char, mbstate_t>;
5673template class codecvt_byname<char32_t, char, mbstate_t>;
5674
5675template class __vector_base_common<true>;
5676
5677_LIBCPP_END_NAMESPACE_STD