blob: 1b242f1206ddea17ba12e835518bc48293b834fd [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 Hinnant6cd05ee2011-09-23 16:11:27 +000022#if _WIN32
Howard Hinnant14fa9f92011-09-29 20:33:10 +000023#include <support/win32/locale_win32.h>
Howard Hinnant6cd05ee2011-09-23 16:11:27 +000024#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000025#include <langinfo.h>
Howard Hinnant6cd05ee2011-09-23 16:11:27 +000026#endif // _!WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000027#include <stdlib.h>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
Howard Hinnant866569b2011-09-28 23:39:33 +000031#ifdef __cloc_defined
Sean Hunt62a6ac32011-07-09 00:56:23 +000032locale_t __cloc() {
33 // In theory this could create a race condition. In practice
34 // the race condition is non-fatal since it will just create
35 // a little resource leak. Better approach would be appreciated.
Sean Hunt62a6ac32011-07-09 00:56:23 +000036 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
37 return result;
Sean Hunt62a6ac32011-07-09 00:56:23 +000038}
Howard Hinnant866569b2011-09-28 23:39:33 +000039#endif // __cloc_defined
Sean Hunt62a6ac32011-07-09 00:56:23 +000040
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000041namespace {
42
43struct release
44{
45 void operator()(locale::facet* p) {p->__release_shared();}
46};
47
48template <class T, class A0>
49inline
50T&
51make(A0 a0)
52{
53 static typename aligned_storage<sizeof(T)>::type buf;
54 ::new (&buf) T(a0);
55 return *(T*)&buf;
56}
57
58template <class T, class A0, class A1>
59inline
60T&
61make(A0 a0, A1 a1)
62{
63 static typename aligned_storage<sizeof(T)>::type buf;
64 ::new (&buf) T(a0, a1);
65 return *(T*)&buf;
66}
67
68template <class T, class A0, class A1, class A2>
69inline
70T&
71make(A0 a0, A1 a1, A2 a2)
72{
73 static typename aligned_storage<sizeof(T)>::type buf;
74 ::new (&buf) T(a0, a1, a2);
75 return *(T*)&buf;
76}
77
78}
79
Howard Hinnantec3773c2011-12-01 20:21:04 +000080#pragma clang diagnostic push
81#pragma clang diagnostic ignored "-Wpadded"
82
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000083class _LIBCPP_HIDDEN locale::__imp
84 : public facet
85{
86 enum {N = 28};
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000087 vector<facet*, __sso_allocator<facet*, N> > facets_;
Howard Hinnantec3773c2011-12-01 20:21:04 +000088 string name_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000089public:
90 explicit __imp(size_t refs = 0);
91 explicit __imp(const string& name, size_t refs = 0);
92 __imp(const __imp&);
93 __imp(const __imp&, const string&, locale::category c);
94 __imp(const __imp& other, const __imp& one, locale::category c);
95 __imp(const __imp&, facet* f, long id);
96 ~__imp();
97
98 const string& name() const {return name_;}
Howard Hinnantec3773c2011-12-01 20:21:04 +000099 bool has_facet(long id) const
100 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101 const locale::facet* use_facet(long id) const;
102
103 static const locale& make_classic();
104 static locale& make_global();
105private:
106 void install(facet* f, long id);
107 template <class F> void install(F* f) {install(f, f->id.__get());}
108 template <class F> void install_from(const __imp& other);
109};
110
Howard Hinnantec3773c2011-12-01 20:21:04 +0000111#pragma clang diagnostic pop
112
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000113locale::__imp::__imp(size_t refs)
114 : facet(refs),
Howard Hinnantec3773c2011-12-01 20:21:04 +0000115 facets_(N),
116 name_("C")
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000117{
118 facets_.clear();
Howard Hinnantec3773c2011-12-01 20:21:04 +0000119 install(&make<_VSTD::collate<char> >(1u));
120 install(&make<_VSTD::collate<wchar_t> >(1u));
121 install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1u));
122 install(&make<_VSTD::ctype<wchar_t> >(1u));
123 install(&make<codecvt<char, char, mbstate_t> >(1u));
124 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
125 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
126 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
127 install(&make<numpunct<char> >(1u));
128 install(&make<numpunct<wchar_t> >(1u));
129 install(&make<num_get<char> >(1u));
130 install(&make<num_get<wchar_t> >(1u));
131 install(&make<num_put<char> >(1u));
132 install(&make<num_put<wchar_t> >(1u));
133 install(&make<moneypunct<char, false> >(1u));
134 install(&make<moneypunct<char, true> >(1u));
135 install(&make<moneypunct<wchar_t, false> >(1u));
136 install(&make<moneypunct<wchar_t, true> >(1u));
137 install(&make<money_get<char> >(1u));
138 install(&make<money_get<wchar_t> >(1u));
139 install(&make<money_put<char> >(1u));
140 install(&make<money_put<wchar_t> >(1u));
141 install(&make<time_get<char> >(1u));
142 install(&make<time_get<wchar_t> >(1u));
143 install(&make<time_put<char> >(1u));
144 install(&make<time_put<wchar_t> >(1u));
145 install(&make<_VSTD::messages<char> >(1u));
146 install(&make<_VSTD::messages<wchar_t> >(1u));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147}
148
149locale::__imp::__imp(const string& name, size_t refs)
150 : facet(refs),
Howard Hinnantec3773c2011-12-01 20:21:04 +0000151 facets_(N),
152 name_(name)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000153{
Howard Hinnantd4444702010-08-11 17:04:31 +0000154#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155 try
156 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000157#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000158 facets_ = locale::classic().__locale_->facets_;
159 for (unsigned i = 0; i < facets_.size(); ++i)
160 if (facets_[i])
161 facets_[i]->__add_shared();
162 install(new collate_byname<char>(name_));
163 install(new collate_byname<wchar_t>(name_));
164 install(new ctype_byname<char>(name_));
165 install(new ctype_byname<wchar_t>(name_));
166 install(new codecvt_byname<char, char, mbstate_t>(name_));
167 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
168 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
169 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
170 install(new numpunct_byname<char>(name_));
171 install(new numpunct_byname<wchar_t>(name_));
172 install(new moneypunct_byname<char, false>(name_));
173 install(new moneypunct_byname<char, true>(name_));
174 install(new moneypunct_byname<wchar_t, false>(name_));
175 install(new moneypunct_byname<wchar_t, true>(name_));
176 install(new time_get_byname<char>(name_));
177 install(new time_get_byname<wchar_t>(name_));
178 install(new time_put_byname<char>(name_));
179 install(new time_put_byname<wchar_t>(name_));
180 install(new messages_byname<char>(name_));
181 install(new messages_byname<wchar_t>(name_));
Howard Hinnantd4444702010-08-11 17:04:31 +0000182#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000183 }
184 catch (...)
185 {
186 for (unsigned i = 0; i < facets_.size(); ++i)
187 if (facets_[i])
188 facets_[i]->__release_shared();
189 throw;
190 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000191#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192}
193
194locale::__imp::__imp(const __imp& other)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000195 : facets_(max<size_t>(N, other.facets_.size())),
196 name_(other.name_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000197{
198 facets_ = other.facets_;
199 for (unsigned i = 0; i < facets_.size(); ++i)
200 if (facets_[i])
201 facets_[i]->__add_shared();
202}
203
204locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000205 : facets_(N),
206 name_("*")
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000207{
208 facets_ = other.facets_;
209 for (unsigned i = 0; i < facets_.size(); ++i)
210 if (facets_[i])
211 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000212#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000213 try
214 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000215#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000216 if (c & locale::collate)
217 {
218 install(new collate_byname<char>(name));
219 install(new collate_byname<wchar_t>(name));
220 }
221 if (c & locale::ctype)
222 {
223 install(new ctype_byname<char>(name));
224 install(new ctype_byname<wchar_t>(name));
225 install(new codecvt_byname<char, char, mbstate_t>(name));
226 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
227 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
228 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
229 }
230 if (c & locale::monetary)
231 {
232 install(new moneypunct_byname<char, false>(name));
233 install(new moneypunct_byname<char, true>(name));
234 install(new moneypunct_byname<wchar_t, false>(name));
235 install(new moneypunct_byname<wchar_t, true>(name));
236 }
237 if (c & locale::numeric)
238 {
239 install(new numpunct_byname<char>(name));
240 install(new numpunct_byname<wchar_t>(name));
241 }
242 if (c & locale::time)
243 {
244 install(new time_get_byname<char>(name));
245 install(new time_get_byname<wchar_t>(name));
246 install(new time_put_byname<char>(name));
247 install(new time_put_byname<wchar_t>(name));
248 }
249 if (c & locale::messages)
250 {
251 install(new messages_byname<char>(name));
252 install(new messages_byname<wchar_t>(name));
253 }
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
266template<class F>
267inline
268void
269locale::__imp::install_from(const locale::__imp& one)
270{
271 long id = F::id.__get();
272 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
273}
274
275locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000276 : facets_(N),
277 name_("*")
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000278{
279 facets_ = other.facets_;
280 for (unsigned i = 0; i < facets_.size(); ++i)
281 if (facets_[i])
282 facets_[i]->__add_shared();
Howard Hinnantd4444702010-08-11 17:04:31 +0000283#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000284 try
285 {
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000286#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000287 if (c & locale::collate)
288 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000289 install_from<_VSTD::collate<char> >(one);
290 install_from<_VSTD::collate<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291 }
292 if (c & locale::ctype)
293 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000294 install_from<_VSTD::ctype<char> >(one);
295 install_from<_VSTD::ctype<wchar_t> >(one);
296 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
297 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
298 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
299 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000300 }
301 if (c & locale::monetary)
302 {
303 install_from<moneypunct<char, false> >(one);
304 install_from<moneypunct<char, true> >(one);
305 install_from<moneypunct<wchar_t, false> >(one);
306 install_from<moneypunct<wchar_t, true> >(one);
307 install_from<money_get<char> >(one);
308 install_from<money_get<wchar_t> >(one);
309 install_from<money_put<char> >(one);
310 install_from<money_put<wchar_t> >(one);
311 }
312 if (c & locale::numeric)
313 {
314 install_from<numpunct<char> >(one);
315 install_from<numpunct<wchar_t> >(one);
316 install_from<num_get<char> >(one);
317 install_from<num_get<wchar_t> >(one);
318 install_from<num_put<char> >(one);
319 install_from<num_put<wchar_t> >(one);
320 }
321 if (c & locale::time)
322 {
323 install_from<time_get<char> >(one);
324 install_from<time_get<wchar_t> >(one);
325 install_from<time_put<char> >(one);
326 install_from<time_put<wchar_t> >(one);
327 }
328 if (c & locale::messages)
329 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000330 install_from<_VSTD::messages<char> >(one);
331 install_from<_VSTD::messages<wchar_t> >(one);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000332 }
Howard Hinnantd4444702010-08-11 17:04:31 +0000333#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334 }
335 catch (...)
336 {
337 for (unsigned i = 0; i < facets_.size(); ++i)
338 if (facets_[i])
339 facets_[i]->__release_shared();
340 throw;
341 }
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000342#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343}
344
345locale::__imp::__imp(const __imp& other, facet* f, long id)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000346 : facets_(max<size_t>(N, other.facets_.size()+1)),
347 name_("*")
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000348{
349 f->__add_shared();
350 unique_ptr<facet, release> hold(f);
351 facets_ = other.facets_;
352 for (unsigned i = 0; i < other.facets_.size(); ++i)
353 if (facets_[i])
354 facets_[i]->__add_shared();
355 install(hold.get(), id);
356}
357
358locale::__imp::~__imp()
359{
360 for (unsigned i = 0; i < facets_.size(); ++i)
361 if (facets_[i])
362 facets_[i]->__release_shared();
363}
364
365void
366locale::__imp::install(facet* f, long id)
367{
368 f->__add_shared();
369 unique_ptr<facet, release> hold(f);
Howard Hinnantec3773c2011-12-01 20:21:04 +0000370 if (static_cast<size_t>(id) >= facets_.size())
371 facets_.resize(static_cast<size_t>(id+1));
372 if (facets_[static_cast<size_t>(id)])
373 facets_[static_cast<size_t>(id)]->__release_shared();
374 facets_[static_cast<size_t>(id)] = hold.release();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000375}
376
377const locale::facet*
378locale::__imp::use_facet(long id) const
379{
Howard Hinnantd4444702010-08-11 17:04:31 +0000380#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381 if (!has_facet(id))
382 throw bad_cast();
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000383#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +0000384 return facets_[static_cast<size_t>(id)];
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000385}
386
387// locale
388
389const locale&
390locale::__imp::make_classic()
391{
392 // only one thread can get in here and it only gets in once
393 static aligned_storage<sizeof(locale)>::type buf;
394 locale* c = (locale*)&buf;
Howard Hinnantec3773c2011-12-01 20:21:04 +0000395 c->__locale_ = &make<__imp>(1u);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000396 return *c;
397}
398
399const locale&
400locale::classic()
401{
402 static const locale& c = __imp::make_classic();
403 return c;
404}
405
406locale&
407locale::__imp::make_global()
408{
409 // only one thread can get in here and it only gets in once
410 static aligned_storage<sizeof(locale)>::type buf;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411 ::new (&buf) locale(locale::classic());
412 return *(locale*)&buf;
413}
414
415locale&
416locale::__global()
417{
418 static locale& g = __imp::make_global();
419 return g;
420}
421
Howard Hinnantc9834542011-05-31 15:34:58 +0000422locale::locale() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423 : __locale_(__global().__locale_)
424{
425 __locale_->__add_shared();
426}
427
Howard Hinnantc9834542011-05-31 15:34:58 +0000428locale::locale(const locale& l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000429 : __locale_(l.__locale_)
430{
431 __locale_->__add_shared();
432}
433
Howard Hinnantc9834542011-05-31 15:34:58 +0000434locale::~locale()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000435{
436 __locale_->__release_shared();
437}
438
439const locale&
Howard Hinnantc9834542011-05-31 15:34:58 +0000440locale::operator=(const locale& other) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441{
442 other.__locale_->__add_shared();
443 __locale_->__release_shared();
444 __locale_ = other.__locale_;
445 return *this;
446}
447
448locale::locale(const char* name)
Howard Hinnantd4444702010-08-11 17:04:31 +0000449#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000450 : __locale_(name ? new __imp(name)
451 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000452#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000453 : __locale_(new __imp(name))
454#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000455{
456 __locale_->__add_shared();
457}
458
459locale::locale(const string& name)
460 : __locale_(new __imp(name))
461{
462 __locale_->__add_shared();
463}
464
465locale::locale(const locale& other, const char* name, category c)
Howard Hinnantd4444702010-08-11 17:04:31 +0000466#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000467 : __locale_(name ? new __imp(*other.__locale_, name, c)
468 : throw runtime_error("locale constructed with null"))
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000469#else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd4444702010-08-11 17:04:31 +0000470 : __locale_(new __imp(*other.__locale_, name, c))
471#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472{
473 __locale_->__add_shared();
474}
475
476locale::locale(const locale& other, const string& name, category c)
477 : __locale_(new __imp(*other.__locale_, name, c))
478{
479 __locale_->__add_shared();
480}
481
482locale::locale(const locale& other, const locale& one, category c)
483 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
484{
485 __locale_->__add_shared();
486}
487
488string
489locale::name() const
490{
491 return __locale_->name();
492}
493
494void
495locale::__install_ctor(const locale& other, facet* f, long id)
496{
497 if (f)
498 __locale_ = new __imp(*other.__locale_, f, id);
499 else
500 __locale_ = other.__locale_;
501 __locale_->__add_shared();
502}
503
504locale
505locale::global(const locale& loc)
506{
507 locale& g = __global();
508 locale r = g;
509 g = loc;
510 if (g.name() != "*")
511 setlocale(LC_ALL, g.name().c_str());
512 return r;
513}
514
515bool
516locale::has_facet(id& x) const
517{
518 return __locale_->has_facet(x.__get());
519}
520
521const locale::facet*
522locale::use_facet(id& x) const
523{
524 return __locale_->use_facet(x.__get());
525}
526
527bool
528locale::operator==(const locale& y) const
529{
530 return (__locale_ == y.__locale_)
531 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
532}
533
534// locale::facet
535
536locale::facet::~facet()
537{
538}
539
540void
Howard Hinnant1694d232011-05-28 14:41:13 +0000541locale::facet::__on_zero_shared() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000542{
543 delete this;
544}
545
546// locale::id
547
548int32_t locale::id::__next_id = 0;
549
550namespace
551{
552
553class __fake_bind
554{
555 locale::id* id_;
556 void (locale::id::* pmf_)();
557public:
558 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
559 : id_(id), pmf_(pmf) {}
560
561 void operator()() const
562 {
563 (id_->*pmf_)();
564 }
565};
566
567}
568
569long
570locale::id::__get()
571{
572 call_once(__flag_, __fake_bind(&locale::id::__init, this));
573 return __id_ - 1;
574}
575
576void
577locale::id::__init()
578{
Howard Hinnantadff4892010-05-24 17:49:41 +0000579 __id_ = __sync_add_and_fetch(&__next_id, 1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580}
581
582// template <> class collate_byname<char>
583
584collate_byname<char>::collate_byname(const char* n, size_t refs)
585 : collate<char>(refs),
586 __l(newlocale(LC_ALL_MASK, n, 0))
587{
Howard Hinnantd4444702010-08-11 17:04:31 +0000588#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000589 if (__l == 0)
590 throw runtime_error("collate_byname<char>::collate_byname"
591 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000592#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000593}
594
595collate_byname<char>::collate_byname(const string& name, size_t refs)
596 : collate<char>(refs),
597 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
598{
Howard Hinnantd4444702010-08-11 17:04:31 +0000599#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000600 if (__l == 0)
601 throw runtime_error("collate_byname<char>::collate_byname"
602 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000603#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000604}
605
606collate_byname<char>::~collate_byname()
607{
608 freelocale(__l);
609}
610
611int
612collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
613 const char_type* __lo2, const char_type* __hi2) const
614{
615 string_type lhs(__lo1, __hi1);
616 string_type rhs(__lo2, __hi2);
617 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
618 if (r < 0)
619 return -1;
620 if (r > 0)
621 return 1;
622 return r;
623}
624
625collate_byname<char>::string_type
626collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
627{
628 const string_type in(lo, hi);
629 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
630 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
631 return out;
632}
633
634// template <> class collate_byname<wchar_t>
635
636collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
637 : collate<wchar_t>(refs),
638 __l(newlocale(LC_ALL_MASK, n, 0))
639{
Howard Hinnantd4444702010-08-11 17:04:31 +0000640#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000641 if (__l == 0)
642 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
643 " failed to construct for " + string(n));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000644#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000645}
646
647collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
648 : collate<wchar_t>(refs),
649 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
650{
Howard Hinnantd4444702010-08-11 17:04:31 +0000651#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000652 if (__l == 0)
653 throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
654 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000655#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000656}
657
658collate_byname<wchar_t>::~collate_byname()
659{
660 freelocale(__l);
661}
662
663int
664collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
665 const char_type* __lo2, const char_type* __hi2) const
666{
667 string_type lhs(__lo1, __hi1);
668 string_type rhs(__lo2, __hi2);
669 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
670 if (r < 0)
671 return -1;
672 if (r > 0)
673 return 1;
674 return r;
675}
676
677collate_byname<wchar_t>::string_type
678collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
679{
680 const string_type in(lo, hi);
681 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
682 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
683 return out;
684}
685
686// template <> class ctype<wchar_t>;
687
688locale::id ctype<wchar_t>::id;
689
690ctype<wchar_t>::~ctype()
691{
692}
693
694bool
695ctype<wchar_t>::do_is(mask m, char_type c) const
696{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000697 return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000698}
699
700const wchar_t*
701ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
702{
703 for (; low != high; ++low, ++vec)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000704 *vec = static_cast<mask>(isascii(*low) ?
705 ctype<char>::classic_table()[*low] : 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000706 return low;
707}
708
709const wchar_t*
710ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
711{
712 for (; low != high; ++low)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000713 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714 break;
715 return low;
716}
717
718const wchar_t*
719ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
720{
721 for (; low != high; ++low)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000722 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723 break;
724 return low;
725}
726
727wchar_t
728ctype<wchar_t>::do_toupper(char_type c) const
729{
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000730#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
731 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
732#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000733 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000734#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000735 return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000736#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000737}
738
739const wchar_t*
740ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
741{
742 for (; low != high; ++low)
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000743#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
744 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
745#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000746 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
747 : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000748#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000749 *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000750#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000751 return low;
752}
753
754wchar_t
755ctype<wchar_t>::do_tolower(char_type c) const
756{
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000757#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
758 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
759#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000760 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000761#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000762 return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000763#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764}
765
766const wchar_t*
767ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
768{
769 for (; low != high; ++low)
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000770#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
771 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
772#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000773 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
774 : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000775#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000776 *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000777#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000778 return low;
779}
780
781wchar_t
782ctype<wchar_t>::do_widen(char c) const
783{
784 return c;
785}
786
787const char*
788ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
789{
790 for (; low != high; ++low, ++dest)
791 *dest = *low;
792 return low;
793}
794
795char
796ctype<wchar_t>::do_narrow(char_type c, char dfault) const
797{
798 if (isascii(c))
799 return static_cast<char>(c);
800 return dfault;
801}
802
803const wchar_t*
804ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
805{
806 for (; low != high; ++low, ++dest)
807 if (isascii(*low))
Howard Hinnantec3773c2011-12-01 20:21:04 +0000808 *dest = static_cast<char>(*low);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000809 else
810 *dest = dfault;
811 return low;
812}
813
814// template <> class ctype<char>;
815
816locale::id ctype<char>::id;
817
818ctype<char>::ctype(const mask* tab, bool del, size_t refs)
819 : locale::facet(refs),
820 __tab_(tab),
821 __del_(del)
822{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000823 if (__tab_ == 0)
824 __tab_ = classic_table();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000825}
826
827ctype<char>::~ctype()
828{
829 if (__tab_ && __del_)
830 delete [] __tab_;
831}
832
833char
834ctype<char>::do_toupper(char_type c) const
835{
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000836#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantec3773c2011-12-01 20:21:04 +0000837 return isascii(c) ?
838 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000839#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000840 return isascii(c) ? __classic_upper_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000841#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000842 return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000843#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000844}
845
846const char*
847ctype<char>::do_toupper(char_type* low, const char_type* high) const
848{
849 for (; low != high; ++low)
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000850#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantec3773c2011-12-01 20:21:04 +0000851 *low = isascii(*low) ?
852 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000853#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000854 *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000855#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000856 *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000857#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000858 return low;
859}
860
861char
862ctype<char>::do_tolower(char_type c) const
863{
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000864#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantec3773c2011-12-01 20:21:04 +0000865 return isascii(c) ?
866 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000867#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000868 return isascii(c) ? __classic_lower_table()[c] : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000869#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000870 return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
Sean Hunte59f7242011-07-09 01:09:31 +0000871#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000872}
873
874const char*
875ctype<char>::do_tolower(char_type* low, const char_type* high) const
876{
877 for (; low != high; ++low)
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000878#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantec3773c2011-12-01 20:21:04 +0000879 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000880#elif defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000881 *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000882#else
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000883 *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
Sean Hunte59f7242011-07-09 01:09:31 +0000884#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000885 return low;
886}
887
888char
889ctype<char>::do_widen(char c) const
890{
891 return c;
892}
893
894const char*
895ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
896{
897 for (; low != high; ++low, ++dest)
898 *dest = *low;
899 return low;
900}
901
902char
903ctype<char>::do_narrow(char_type c, char dfault) const
904{
905 if (isascii(c))
906 return static_cast<char>(c);
907 return dfault;
908}
909
910const char*
911ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
912{
913 for (; low != high; ++low, ++dest)
914 if (isascii(*low))
915 *dest = *low;
916 else
917 *dest = dfault;
918 return low;
919}
920
921const ctype<char>::mask*
Howard Hinnantc9834542011-05-31 15:34:58 +0000922ctype<char>::classic_table() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000923{
David Chisnallc512df12011-09-21 08:39:44 +0000924#if defined(__APPLE__) || defined(__FreeBSD__)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000925 return _DefaultRuneLocale.__runetype;
Sean Hunt62a6ac32011-07-09 00:56:23 +0000926#elif defined(__GLIBC__)
927 return __cloc()->__ctype_b;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000928#elif _WIN32
929 return _ctype+1; // internal ctype mask table defined in msvcrt.dll
David Chisnallc512df12011-09-21 08:39:44 +0000930// This is assumed to be safe, which is a nonsense assumption because we're
931// going to end up dereferencing it later...
Sean Hunt62a6ac32011-07-09 00:56:23 +0000932#else
933 return NULL;
934#endif
935}
936
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000937#if defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000938const int*
939ctype<char>::__classic_lower_table() _NOEXCEPT
940{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000941 return __cloc()->__ctype_tolower;
Sean Hunt62a6ac32011-07-09 00:56:23 +0000942}
943
944const int*
945ctype<char>::__classic_upper_table() _NOEXCEPT
946{
Sean Hunt62a6ac32011-07-09 00:56:23 +0000947 return __cloc()->__ctype_toupper;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000948}
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000949#endif // __GLIBC__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000950
951// template <> class ctype_byname<char>
952
953ctype_byname<char>::ctype_byname(const char* name, size_t refs)
954 : ctype<char>(0, false, refs),
955 __l(newlocale(LC_ALL_MASK, name, 0))
956{
Howard Hinnantd4444702010-08-11 17:04:31 +0000957#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000958 if (__l == 0)
959 throw runtime_error("ctype_byname<char>::ctype_byname"
960 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000961#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000962}
963
964ctype_byname<char>::ctype_byname(const string& name, size_t refs)
965 : ctype<char>(0, false, refs),
966 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
967{
Howard Hinnantd4444702010-08-11 17:04:31 +0000968#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000969 if (__l == 0)
970 throw runtime_error("ctype_byname<char>::ctype_byname"
971 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000972#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000973}
974
975ctype_byname<char>::~ctype_byname()
976{
977 freelocale(__l);
978}
979
980char
981ctype_byname<char>::do_toupper(char_type c) const
982{
Howard Hinnantec3773c2011-12-01 20:21:04 +0000983 return static_cast<char>(toupper_l(c, __l));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000984}
985
986const char*
987ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
988{
989 for (; low != high; ++low)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000990 *low = static_cast<char>(toupper_l(*low, __l));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000991 return low;
992}
993
994char
995ctype_byname<char>::do_tolower(char_type c) const
996{
Howard Hinnantec3773c2011-12-01 20:21:04 +0000997 return static_cast<char>(tolower_l(c, __l));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000998}
999
1000const char*
1001ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1002{
1003 for (; low != high; ++low)
Howard Hinnantec3773c2011-12-01 20:21:04 +00001004 *low = static_cast<char>(tolower_l(*low, __l));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001005 return low;
1006}
1007
1008// template <> class ctype_byname<wchar_t>
1009
1010ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1011 : ctype<wchar_t>(refs),
1012 __l(newlocale(LC_ALL_MASK, name, 0))
1013{
Howard Hinnantd4444702010-08-11 17:04:31 +00001014#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001015 if (__l == 0)
1016 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1017 " failed to construct for " + string(name));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001018#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001019}
1020
1021ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1022 : ctype<wchar_t>(refs),
1023 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1024{
Howard Hinnantd4444702010-08-11 17:04:31 +00001025#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001026 if (__l == 0)
1027 throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1028 " failed to construct for " + name);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001029#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001030}
1031
1032ctype_byname<wchar_t>::~ctype_byname()
1033{
1034 freelocale(__l);
1035}
1036
1037bool
1038ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1039{
Sean Hunt6f0342c2011-07-09 03:40:04 +00001040#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001041 return static_cast<bool>(iswctype_l(c, m, __l));
Sean Hunt6f0342c2011-07-09 03:40:04 +00001042#else
Howard Hinnant8db4aca2011-10-17 20:08:59 +00001043 bool result = true;
Howard Hinnant3c466fc2011-09-29 13:33:15 +00001044 if (m & space && !iswspace_l(c, __l)) result = false;
1045 if (m & print && !iswprint_l(c, __l)) result = false;
1046 if (m & cntrl && !iswcntrl_l(c, __l)) result = false;
1047 if (m & upper && !iswupper_l(c, __l)) result = false;
1048 if (m & lower && !iswlower_l(c, __l)) result = false;
1049 if (m & alpha && !iswalpha_l(c, __l)) result = false;
1050 if (m & digit && !iswdigit_l(c, __l)) result = false;
1051 if (m & punct && !iswpunct_l(c, __l)) result = false;
1052 if (m & xdigit && !iswxdigit_l(c, __l)) result = false;
1053 if (m & blank && !iswblank_l(c, __l)) result = false;
1054 return result;
Sean Hunt6f0342c2011-07-09 03:40:04 +00001055#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001056}
1057
1058const wchar_t*
1059ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1060{
1061 for (; low != high; ++low, ++vec)
1062 {
1063 if (isascii(*low))
Sean Hunt62a6ac32011-07-09 00:56:23 +00001064 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001065 else
1066 {
1067 *vec = 0;
1068 if (iswspace_l(*low, __l))
1069 *vec |= space;
1070 if (iswprint_l(*low, __l))
1071 *vec |= print;
1072 if (iswcntrl_l(*low, __l))
1073 *vec |= cntrl;
1074 if (iswupper_l(*low, __l))
1075 *vec |= upper;
1076 if (iswlower_l(*low, __l))
1077 *vec |= lower;
1078 if (iswalpha_l(*low, __l))
1079 *vec |= alpha;
1080 if (iswdigit_l(*low, __l))
1081 *vec |= digit;
1082 if (iswpunct_l(*low, __l))
1083 *vec |= punct;
1084 if (iswxdigit_l(*low, __l))
1085 *vec |= xdigit;
1086 }
1087 }
1088 return low;
1089}
1090
1091const wchar_t*
1092ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1093{
1094 for (; low != high; ++low)
Sean Hunt6f0342c2011-07-09 03:40:04 +00001095 {
1096#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001097 if (iswctype_l(*low, m, __l))
1098 break;
Sean Hunt6f0342c2011-07-09 03:40:04 +00001099#else
1100 if (m & space && !iswspace_l(*low, __l)) continue;
1101 if (m & print && !iswprint_l(*low, __l)) continue;
1102 if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
1103 if (m & upper && !iswupper_l(*low, __l)) continue;
1104 if (m & lower && !iswlower_l(*low, __l)) continue;
1105 if (m & alpha && !iswalpha_l(*low, __l)) continue;
1106 if (m & digit && !iswdigit_l(*low, __l)) continue;
1107 if (m & punct && !iswpunct_l(*low, __l)) continue;
1108 if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
1109 if (m & blank && !iswblank_l(*low, __l)) continue;
1110 break;
1111#endif
1112 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 return low;
1114}
1115
1116const wchar_t*
1117ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1118{
1119 for (; low != high; ++low)
Sean Hunt6f0342c2011-07-09 03:40:04 +00001120 {
1121#ifdef _LIBCPP_WCTYPE_IS_MASK
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001122 if (!iswctype_l(*low, m, __l))
1123 break;
Sean Hunt6f0342c2011-07-09 03:40:04 +00001124#else
1125 if (m & space && iswspace_l(*low, __l)) continue;
1126 if (m & print && iswprint_l(*low, __l)) continue;
1127 if (m & cntrl && iswcntrl_l(*low, __l)) continue;
1128 if (m & upper && iswupper_l(*low, __l)) continue;
1129 if (m & lower && iswlower_l(*low, __l)) continue;
1130 if (m & alpha && iswalpha_l(*low, __l)) continue;
1131 if (m & digit && iswdigit_l(*low, __l)) continue;
1132 if (m & punct && iswpunct_l(*low, __l)) continue;
1133 if (m & xdigit && iswxdigit_l(*low, __l)) continue;
1134 if (m & blank && iswblank_l(*low, __l)) continue;
1135 break;
1136#endif
1137 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001138 return low;
1139}
1140
1141wchar_t
1142ctype_byname<wchar_t>::do_toupper(char_type c) const
1143{
1144 return towupper_l(c, __l);
1145}
1146
1147const wchar_t*
1148ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1149{
1150 for (; low != high; ++low)
1151 *low = towupper_l(*low, __l);
1152 return low;
1153}
1154
1155wchar_t
1156ctype_byname<wchar_t>::do_tolower(char_type c) const
1157{
1158 return towlower_l(c, __l);
1159}
1160
1161const wchar_t*
1162ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1163{
1164 for (; low != high; ++low)
1165 *low = towlower_l(*low, __l);
1166 return low;
1167}
1168
1169wchar_t
1170ctype_byname<wchar_t>::do_widen(char c) const
1171{
Howard Hinnant866569b2011-09-28 23:39:33 +00001172#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001173 return btowc_l(c, __l);
1174#else
1175 return __btowc_l(c, __l);
1176#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001177}
1178
1179const char*
1180ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1181{
1182 for (; low != high; ++low, ++dest)
Howard Hinnant866569b2011-09-28 23:39:33 +00001183#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001184 *dest = btowc_l(*low, __l);
1185#else
1186 *dest = __btowc_l(*low, __l);
1187#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001188 return low;
1189}
1190
1191char
1192ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1193{
Howard Hinnant866569b2011-09-28 23:39:33 +00001194#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001195 int r = wctob_l(c, __l);
1196#else
1197 int r = __wctob_l(c, __l);
1198#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001199 return r != WEOF ? static_cast<char>(r) : dfault;
1200}
1201
1202const wchar_t*
1203ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1204{
1205 for (; low != high; ++low, ++dest)
1206 {
Howard Hinnant866569b2011-09-28 23:39:33 +00001207#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001208 int r = wctob_l(*low, __l);
1209#else
1210 int r = __wctob_l(*low, __l);
1211#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001212 *dest = r != WEOF ? static_cast<char>(r) : dfault;
1213 }
1214 return low;
1215}
1216
1217// template <> class codecvt<char, char, mbstate_t>
1218
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001219locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001220
1221codecvt<char, char, mbstate_t>::~codecvt()
1222{
1223}
1224
1225codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001226codecvt<char, char, mbstate_t>::do_out(state_type&,
1227 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001228 extern_type* to, extern_type*, extern_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_in(state_type&,
1237 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001238 intern_type* to, intern_type*, intern_type*& to_nxt) const
1239{
1240 frm_nxt = frm;
1241 to_nxt = to;
1242 return noconv;
1243}
1244
1245codecvt<char, char, mbstate_t>::result
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001246codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001247 extern_type* to, extern_type*, extern_type*& to_nxt) const
1248{
1249 to_nxt = to;
1250 return noconv;
1251}
1252
1253int
Howard Hinnantc9834542011-05-31 15:34:58 +00001254codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001255{
1256 return 1;
1257}
1258
1259bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001260codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001261{
1262 return true;
1263}
1264
1265int
1266codecvt<char, char, mbstate_t>::do_length(state_type&,
1267 const extern_type* frm, const extern_type* end, size_t mx) const
1268{
Howard Hinnantec3773c2011-12-01 20:21:04 +00001269 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001270}
1271
1272int
Howard Hinnantc9834542011-05-31 15:34:58 +00001273codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001274{
1275 return 1;
1276}
1277
1278// template <> class codecvt<wchar_t, char, mbstate_t>
1279
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001280locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001281
1282codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1283 : locale::facet(refs),
1284 __l(0)
1285{
1286}
1287
1288codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1289 : locale::facet(refs),
1290 __l(newlocale(LC_ALL_MASK, nm, 0))
1291{
Howard Hinnantd4444702010-08-11 17:04:31 +00001292#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001293 if (__l == 0)
1294 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1295 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001296#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001297}
1298
1299codecvt<wchar_t, char, mbstate_t>::~codecvt()
1300{
1301 if (__l != 0)
1302 freelocale(__l);
1303}
1304
1305codecvt<wchar_t, char, mbstate_t>::result
1306codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001307 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001308 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1309{
1310 // look for first internal null in frm
1311 const intern_type* fend = frm;
1312 for (; fend != frm_end; ++fend)
1313 if (*fend == 0)
1314 break;
1315 // loop over all null-terminated sequences in frm
1316 to_nxt = to;
1317 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1318 {
1319 // save state in case needed to reover to_nxt on error
1320 mbstate_t save_state = st;
Howard Hinnant866569b2011-09-28 23:39:33 +00001321#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +00001322 size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1323 static_cast<size_t>(to_end-to), &st, __l);
Sean Huntf3907e62011-07-15 05:40:33 +00001324#else
1325 size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1326#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001327 if (n == size_t(-1))
1328 {
1329 // need to recover to_nxt
1330 for (to_nxt = to; frm != frm_nxt; ++frm)
1331 {
Howard Hinnant866569b2011-09-28 23:39:33 +00001332#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001333 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1334#else
1335 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1336#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001337 if (n == size_t(-1))
1338 break;
1339 to_nxt += n;
1340 }
1341 frm_nxt = frm;
1342 return error;
1343 }
1344 if (n == 0)
1345 return partial;
1346 to_nxt += n;
1347 if (to_nxt == to_end)
1348 break;
1349 if (fend != frm_end) // set up next null terminated sequence
1350 {
1351 // Try to write the terminating null
1352 extern_type tmp[MB_LEN_MAX];
Howard Hinnant866569b2011-09-28 23:39:33 +00001353#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001354 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1355#else
1356 n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1357#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001358 if (n == size_t(-1)) // on error
1359 return error;
Howard Hinnantec3773c2011-12-01 20:21:04 +00001360 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001361 return partial;
1362 for (extern_type* p = tmp; n; --n) // write it
1363 *to_nxt++ = *p++;
1364 ++frm_nxt;
1365 // look for next null in frm
1366 for (fend = frm_nxt; fend != frm_end; ++fend)
1367 if (*fend == 0)
1368 break;
1369 }
1370 }
1371 return frm_nxt == frm_end ? ok : partial;
1372}
1373
1374codecvt<wchar_t, char, mbstate_t>::result
1375codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00001376 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001377 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1378{
1379 // look for first internal null in frm
1380 const extern_type* fend = frm;
1381 for (; fend != frm_end; ++fend)
1382 if (*fend == 0)
1383 break;
1384 // loop over all null-terminated sequences in frm
1385 to_nxt = to;
1386 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1387 {
1388 // save state in case needed to reover to_nxt on error
1389 mbstate_t save_state = st;
Howard Hinnant866569b2011-09-28 23:39:33 +00001390#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +00001391 size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1392 static_cast<size_t>(to_end-to), &st, __l);
Sean Huntf3907e62011-07-15 05:40:33 +00001393#else
1394 size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1395#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001396 if (n == size_t(-1))
1397 {
1398 // need to recover to_nxt
1399 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1400 {
Howard Hinnant866569b2011-09-28 23:39:33 +00001401#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +00001402 n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1403 &save_state, __l);
Sean Huntf3907e62011-07-15 05:40:33 +00001404#else
1405 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1406#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001407 switch (n)
1408 {
1409 case 0:
1410 ++frm;
1411 break;
Howard Hinnant982331b2012-02-08 19:15:06 +00001412 case size_t(-1):
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001413 frm_nxt = frm;
1414 return error;
Howard Hinnant982331b2012-02-08 19:15:06 +00001415 case size_t(-2):
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001416 frm_nxt = frm;
1417 return partial;
1418 default:
1419 frm += n;
1420 break;
1421 }
1422 }
1423 frm_nxt = frm;
1424 return frm_nxt == frm_end ? ok : partial;
1425 }
1426 if (n == 0)
1427 return error;
1428 to_nxt += n;
1429 if (to_nxt == to_end)
1430 break;
1431 if (fend != frm_end) // set up next null terminated sequence
1432 {
1433 // Try to write the terminating null
Howard Hinnant866569b2011-09-28 23:39:33 +00001434#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001435 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1436#else
1437 n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1438#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001439 if (n != 0) // on error
1440 return error;
1441 ++to_nxt;
1442 ++frm_nxt;
1443 // look for next null in frm
1444 for (fend = frm_nxt; fend != frm_end; ++fend)
1445 if (*fend == 0)
1446 break;
1447 }
1448 }
1449 return frm_nxt == frm_end ? ok : partial;
1450}
1451
1452codecvt<wchar_t, char, mbstate_t>::result
1453codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1454 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1455{
1456 to_nxt = to;
1457 extern_type tmp[MB_LEN_MAX];
Howard Hinnant866569b2011-09-28 23:39:33 +00001458#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001459 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1460#else
1461 size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1462#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001463 if (n == size_t(-1) || n == 0) // on error
1464 return error;
1465 --n;
Howard Hinnantec3773c2011-12-01 20:21:04 +00001466 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001467 return partial;
1468 for (extern_type* p = tmp; n; --n) // write it
1469 *to_nxt++ = *p++;
1470 return ok;
1471}
1472
1473int
Howard Hinnantc9834542011-05-31 15:34:58 +00001474codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475{
Howard Hinnant866569b2011-09-28 23:39:33 +00001476#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001477 if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1478#else
1479 if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1480#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001481 {
1482 // stateless encoding
Howard Hinnant866569b2011-09-28 23:39:33 +00001483#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001484 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1485#else
1486 if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1487#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001488 return 1; // which take more than 1 char to form a wchar_t
1489 return 0;
1490 }
1491 return -1;
1492}
1493
1494bool
Howard Hinnantc9834542011-05-31 15:34:58 +00001495codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001496{
1497 return false;
1498}
1499
1500int
1501codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1502 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1503{
1504 int nbytes = 0;
1505 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1506 {
Howard Hinnant866569b2011-09-28 23:39:33 +00001507#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +00001508 size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
Sean Huntf3907e62011-07-15 05:40:33 +00001509#else
1510 size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1511#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001512 switch (n)
1513 {
1514 case 0:
1515 ++nbytes;
1516 ++frm;
1517 break;
Howard Hinnant982331b2012-02-08 19:15:06 +00001518 case size_t(-1):
1519 case size_t(-2):
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001520 return nbytes;
1521 default:
1522 nbytes += n;
1523 frm += n;
1524 break;
1525 }
1526 }
1527 return nbytes;
1528}
1529
1530int
Howard Hinnantc9834542011-05-31 15:34:58 +00001531codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001532{
Howard Hinnant866569b2011-09-28 23:39:33 +00001533#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00001534 return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
1535#else
1536 return __l == 0 ? 1 : __mb_cur_max_l(__l);
1537#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001538}
1539
1540// Valid UTF ranges
1541// UTF-32 UTF-16 UTF-8 # of code points
1542// first second first second third fourth
1543// 000000 - 00007F 0000 - 007F 00 - 7F 127
1544// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1545// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1546// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1547// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1548// 00D800 - 00DFFF invalid
1549// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1550// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1551// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1552// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1553
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00001554static
1555codecvt_base::result
1556utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1557 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1558 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1559{
1560 frm_nxt = frm;
1561 to_nxt = to;
1562 if (mode & generate_header)
1563 {
1564 if (to_end-to_nxt < 3)
1565 return codecvt_base::partial;
1566 *to_nxt++ = static_cast<uint8_t>(0xEF);
1567 *to_nxt++ = static_cast<uint8_t>(0xBB);
1568 *to_nxt++ = static_cast<uint8_t>(0xBF);
1569 }
1570 for (; frm_nxt < frm_end; ++frm_nxt)
1571 {
1572 uint16_t wc1 = *frm_nxt;
1573 if (wc1 > Maxcode)
1574 return codecvt_base::error;
1575 if (wc1 < 0x0080)
1576 {
1577 if (to_end-to_nxt < 1)
1578 return codecvt_base::partial;
1579 *to_nxt++ = static_cast<uint8_t>(wc1);
1580 }
1581 else if (wc1 < 0x0800)
1582 {
1583 if (to_end-to_nxt < 2)
1584 return codecvt_base::partial;
1585 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1586 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1587 }
1588 else if (wc1 < 0xD800)
1589 {
1590 if (to_end-to_nxt < 3)
1591 return codecvt_base::partial;
1592 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1593 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1594 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1595 }
1596 else if (wc1 < 0xDC00)
1597 {
1598 if (frm_end-frm_nxt < 2)
1599 return codecvt_base::partial;
1600 uint16_t wc2 = frm_nxt[1];
1601 if ((wc2 & 0xFC00) != 0xDC00)
1602 return codecvt_base::error;
1603 if (to_end-to_nxt < 4)
1604 return codecvt_base::partial;
1605 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1606 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1607 return codecvt_base::error;
1608 ++frm_nxt;
1609 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1610 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1611 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1612 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1613 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1614 }
1615 else if (wc1 < 0xE000)
1616 {
1617 return codecvt_base::error;
1618 }
1619 else
1620 {
1621 if (to_end-to_nxt < 3)
1622 return codecvt_base::partial;
1623 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1624 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1625 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1626 }
1627 }
1628 return codecvt_base::ok;
1629}
1630
1631static
1632codecvt_base::result
1633utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1634 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1635 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1636{
1637 frm_nxt = frm;
1638 to_nxt = to;
1639 if (mode & generate_header)
1640 {
1641 if (to_end-to_nxt < 3)
1642 return codecvt_base::partial;
1643 *to_nxt++ = static_cast<uint8_t>(0xEF);
1644 *to_nxt++ = static_cast<uint8_t>(0xBB);
1645 *to_nxt++ = static_cast<uint8_t>(0xBF);
1646 }
1647 for (; frm_nxt < frm_end; ++frm_nxt)
1648 {
1649 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1650 if (wc1 > Maxcode)
1651 return codecvt_base::error;
1652 if (wc1 < 0x0080)
1653 {
1654 if (to_end-to_nxt < 1)
1655 return codecvt_base::partial;
1656 *to_nxt++ = static_cast<uint8_t>(wc1);
1657 }
1658 else if (wc1 < 0x0800)
1659 {
1660 if (to_end-to_nxt < 2)
1661 return codecvt_base::partial;
1662 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1663 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1664 }
1665 else if (wc1 < 0xD800)
1666 {
1667 if (to_end-to_nxt < 3)
1668 return codecvt_base::partial;
1669 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1670 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1671 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1672 }
1673 else if (wc1 < 0xDC00)
1674 {
1675 if (frm_end-frm_nxt < 2)
1676 return codecvt_base::partial;
1677 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1678 if ((wc2 & 0xFC00) != 0xDC00)
1679 return codecvt_base::error;
1680 if (to_end-to_nxt < 4)
1681 return codecvt_base::partial;
1682 if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1683 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1684 return codecvt_base::error;
1685 ++frm_nxt;
1686 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1687 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1688 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1689 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1690 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1691 }
1692 else if (wc1 < 0xE000)
1693 {
1694 return codecvt_base::error;
1695 }
1696 else
1697 {
1698 if (to_end-to_nxt < 3)
1699 return codecvt_base::partial;
1700 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1701 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1702 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1703 }
1704 }
1705 return codecvt_base::ok;
1706}
1707
1708static
1709codecvt_base::result
1710utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1711 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1712 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1713{
1714 frm_nxt = frm;
1715 to_nxt = to;
1716 if (mode & consume_header)
1717 {
1718 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1719 frm_nxt[2] == 0xBF)
1720 frm_nxt += 3;
1721 }
1722 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1723 {
1724 uint8_t c1 = *frm_nxt;
1725 if (c1 > Maxcode)
1726 return codecvt_base::error;
1727 if (c1 < 0x80)
1728 {
1729 *to_nxt = static_cast<uint16_t>(c1);
1730 ++frm_nxt;
1731 }
1732 else if (c1 < 0xC2)
1733 {
1734 return codecvt_base::error;
1735 }
1736 else if (c1 < 0xE0)
1737 {
1738 if (frm_end-frm_nxt < 2)
1739 return codecvt_base::partial;
1740 uint8_t c2 = frm_nxt[1];
1741 if ((c2 & 0xC0) != 0x80)
1742 return codecvt_base::error;
1743 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1744 if (t > Maxcode)
1745 return codecvt_base::error;
1746 *to_nxt = t;
1747 frm_nxt += 2;
1748 }
1749 else if (c1 < 0xF0)
1750 {
1751 if (frm_end-frm_nxt < 3)
1752 return codecvt_base::partial;
1753 uint8_t c2 = frm_nxt[1];
1754 uint8_t c3 = frm_nxt[2];
1755 switch (c1)
1756 {
1757 case 0xE0:
1758 if ((c2 & 0xE0) != 0xA0)
1759 return codecvt_base::error;
1760 break;
1761 case 0xED:
1762 if ((c2 & 0xE0) != 0x80)
1763 return codecvt_base::error;
1764 break;
1765 default:
1766 if ((c2 & 0xC0) != 0x80)
1767 return codecvt_base::error;
1768 break;
1769 }
1770 if ((c3 & 0xC0) != 0x80)
1771 return codecvt_base::error;
1772 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1773 | ((c2 & 0x3F) << 6)
1774 | (c3 & 0x3F));
1775 if (t > Maxcode)
1776 return codecvt_base::error;
1777 *to_nxt = t;
1778 frm_nxt += 3;
1779 }
1780 else if (c1 < 0xF5)
1781 {
1782 if (frm_end-frm_nxt < 4)
1783 return codecvt_base::partial;
1784 uint8_t c2 = frm_nxt[1];
1785 uint8_t c3 = frm_nxt[2];
1786 uint8_t c4 = frm_nxt[3];
1787 switch (c1)
1788 {
1789 case 0xF0:
1790 if (!(0x90 <= c2 && c2 <= 0xBF))
1791 return codecvt_base::error;
1792 break;
1793 case 0xF4:
1794 if ((c2 & 0xF0) != 0x80)
1795 return codecvt_base::error;
1796 break;
1797 default:
1798 if ((c2 & 0xC0) != 0x80)
1799 return codecvt_base::error;
1800 break;
1801 }
1802 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1803 return codecvt_base::error;
1804 if (to_end-to_nxt < 2)
1805 return codecvt_base::partial;
1806 if (((((unsigned long)c1 & 7) << 18) +
1807 (((unsigned long)c2 & 0x3F) << 12) +
1808 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1809 return codecvt_base::error;
1810 *to_nxt = static_cast<uint16_t>(
1811 0xD800
1812 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1813 | ((c2 & 0x0F) << 2)
1814 | ((c3 & 0x30) >> 4));
1815 *++to_nxt = static_cast<uint16_t>(
1816 0xDC00
1817 | ((c3 & 0x0F) << 6)
1818 | (c4 & 0x3F));
1819 frm_nxt += 4;
1820 }
1821 else
1822 {
1823 return codecvt_base::error;
1824 }
1825 }
1826 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1827}
1828
1829static
1830codecvt_base::result
1831utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1832 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1833 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1834{
1835 frm_nxt = frm;
1836 to_nxt = to;
1837 if (mode & consume_header)
1838 {
1839 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1840 frm_nxt[2] == 0xBF)
1841 frm_nxt += 3;
1842 }
1843 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1844 {
1845 uint8_t c1 = *frm_nxt;
1846 if (c1 > Maxcode)
1847 return codecvt_base::error;
1848 if (c1 < 0x80)
1849 {
1850 *to_nxt = static_cast<uint32_t>(c1);
1851 ++frm_nxt;
1852 }
1853 else if (c1 < 0xC2)
1854 {
1855 return codecvt_base::error;
1856 }
1857 else if (c1 < 0xE0)
1858 {
1859 if (frm_end-frm_nxt < 2)
1860 return codecvt_base::partial;
1861 uint8_t c2 = frm_nxt[1];
1862 if ((c2 & 0xC0) != 0x80)
1863 return codecvt_base::error;
1864 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1865 if (t > Maxcode)
1866 return codecvt_base::error;
1867 *to_nxt = static_cast<uint32_t>(t);
1868 frm_nxt += 2;
1869 }
1870 else if (c1 < 0xF0)
1871 {
1872 if (frm_end-frm_nxt < 3)
1873 return codecvt_base::partial;
1874 uint8_t c2 = frm_nxt[1];
1875 uint8_t c3 = frm_nxt[2];
1876 switch (c1)
1877 {
1878 case 0xE0:
1879 if ((c2 & 0xE0) != 0xA0)
1880 return codecvt_base::error;
1881 break;
1882 case 0xED:
1883 if ((c2 & 0xE0) != 0x80)
1884 return codecvt_base::error;
1885 break;
1886 default:
1887 if ((c2 & 0xC0) != 0x80)
1888 return codecvt_base::error;
1889 break;
1890 }
1891 if ((c3 & 0xC0) != 0x80)
1892 return codecvt_base::error;
1893 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1894 | ((c2 & 0x3F) << 6)
1895 | (c3 & 0x3F));
1896 if (t > Maxcode)
1897 return codecvt_base::error;
1898 *to_nxt = static_cast<uint32_t>(t);
1899 frm_nxt += 3;
1900 }
1901 else if (c1 < 0xF5)
1902 {
1903 if (frm_end-frm_nxt < 4)
1904 return codecvt_base::partial;
1905 uint8_t c2 = frm_nxt[1];
1906 uint8_t c3 = frm_nxt[2];
1907 uint8_t c4 = frm_nxt[3];
1908 switch (c1)
1909 {
1910 case 0xF0:
1911 if (!(0x90 <= c2 && c2 <= 0xBF))
1912 return codecvt_base::error;
1913 break;
1914 case 0xF4:
1915 if ((c2 & 0xF0) != 0x80)
1916 return codecvt_base::error;
1917 break;
1918 default:
1919 if ((c2 & 0xC0) != 0x80)
1920 return codecvt_base::error;
1921 break;
1922 }
1923 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1924 return codecvt_base::error;
1925 if (to_end-to_nxt < 2)
1926 return codecvt_base::partial;
1927 if (((((unsigned long)c1 & 7) << 18) +
1928 (((unsigned long)c2 & 0x3F) << 12) +
1929 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1930 return codecvt_base::error;
1931 *to_nxt = static_cast<uint32_t>(
1932 0xD800
1933 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1934 | ((c2 & 0x0F) << 2)
1935 | ((c3 & 0x30) >> 4));
1936 *++to_nxt = static_cast<uint32_t>(
1937 0xDC00
1938 | ((c3 & 0x0F) << 6)
1939 | (c4 & 0x3F));
1940 frm_nxt += 4;
1941 }
1942 else
1943 {
1944 return codecvt_base::error;
1945 }
1946 }
1947 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1948}
1949
1950static
1951int
1952utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1953 size_t mx, unsigned long Maxcode = 0x10FFFF,
1954 codecvt_mode mode = codecvt_mode(0))
1955{
1956 const uint8_t* frm_nxt = frm;
1957 if (mode & consume_header)
1958 {
1959 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1960 frm_nxt[2] == 0xBF)
1961 frm_nxt += 3;
1962 }
1963 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1964 {
1965 uint8_t c1 = *frm_nxt;
1966 if (c1 > Maxcode)
1967 break;
1968 if (c1 < 0x80)
1969 {
1970 ++frm_nxt;
1971 }
1972 else if (c1 < 0xC2)
1973 {
1974 break;
1975 }
1976 else if (c1 < 0xE0)
1977 {
1978 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1979 break;
1980 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1981 if (t > Maxcode)
1982 break;
1983 frm_nxt += 2;
1984 }
1985 else if (c1 < 0xF0)
1986 {
1987 if (frm_end-frm_nxt < 3)
1988 break;
1989 uint8_t c2 = frm_nxt[1];
1990 uint8_t c3 = frm_nxt[2];
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00001991 switch (c1)
1992 {
1993 case 0xE0:
1994 if ((c2 & 0xE0) != 0xA0)
1995 return static_cast<int>(frm_nxt - frm);
1996 break;
1997 case 0xED:
1998 if ((c2 & 0xE0) != 0x80)
1999 return static_cast<int>(frm_nxt - frm);
2000 break;
2001 default:
2002 if ((c2 & 0xC0) != 0x80)
2003 return static_cast<int>(frm_nxt - frm);
2004 break;
2005 }
2006 if ((c3 & 0xC0) != 0x80)
2007 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002008 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002009 break;
2010 frm_nxt += 3;
2011 }
2012 else if (c1 < 0xF5)
2013 {
2014 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2015 break;
2016 uint8_t c2 = frm_nxt[1];
2017 uint8_t c3 = frm_nxt[2];
2018 uint8_t c4 = frm_nxt[3];
2019 switch (c1)
2020 {
2021 case 0xF0:
2022 if (!(0x90 <= c2 && c2 <= 0xBF))
2023 return static_cast<int>(frm_nxt - frm);
2024 break;
2025 case 0xF4:
2026 if ((c2 & 0xF0) != 0x80)
2027 return static_cast<int>(frm_nxt - frm);
2028 break;
2029 default:
2030 if ((c2 & 0xC0) != 0x80)
2031 return static_cast<int>(frm_nxt - frm);
2032 break;
2033 }
2034 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2035 break;
2036 if (((((unsigned long)c1 & 7) << 18) +
2037 (((unsigned long)c2 & 0x3F) << 12) +
2038 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
2039 break;
2040 ++nchar16_t;
2041 frm_nxt += 4;
2042 }
2043 else
2044 {
2045 break;
2046 }
2047 }
2048 return static_cast<int>(frm_nxt - frm);
2049}
2050
2051static
2052codecvt_base::result
2053ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2054 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2055 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2056{
2057 frm_nxt = frm;
2058 to_nxt = to;
2059 if (mode & generate_header)
2060 {
2061 if (to_end-to_nxt < 3)
2062 return codecvt_base::partial;
2063 *to_nxt++ = static_cast<uint8_t>(0xEF);
2064 *to_nxt++ = static_cast<uint8_t>(0xBB);
2065 *to_nxt++ = static_cast<uint8_t>(0xBF);
2066 }
2067 for (; frm_nxt < frm_end; ++frm_nxt)
2068 {
2069 uint32_t wc = *frm_nxt;
2070 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2071 return codecvt_base::error;
2072 if (wc < 0x000080)
2073 {
2074 if (to_end-to_nxt < 1)
2075 return codecvt_base::partial;
2076 *to_nxt++ = static_cast<uint8_t>(wc);
2077 }
2078 else if (wc < 0x000800)
2079 {
2080 if (to_end-to_nxt < 2)
2081 return codecvt_base::partial;
2082 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2083 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2084 }
2085 else if (wc < 0x010000)
2086 {
2087 if (to_end-to_nxt < 3)
2088 return codecvt_base::partial;
2089 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2090 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2091 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2092 }
2093 else // if (wc < 0x110000)
2094 {
2095 if (to_end-to_nxt < 4)
2096 return codecvt_base::partial;
2097 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2098 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2099 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2100 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2101 }
2102 }
2103 return codecvt_base::ok;
2104}
2105
2106static
2107codecvt_base::result
2108utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2109 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2110 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2111{
2112 frm_nxt = frm;
2113 to_nxt = to;
2114 if (mode & consume_header)
2115 {
2116 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2117 frm_nxt[2] == 0xBF)
2118 frm_nxt += 3;
2119 }
2120 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2121 {
2122 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2123 if (c1 < 0x80)
2124 {
2125 if (c1 > Maxcode)
2126 return codecvt_base::error;
2127 *to_nxt = static_cast<uint32_t>(c1);
2128 ++frm_nxt;
2129 }
2130 else if (c1 < 0xC2)
2131 {
2132 return codecvt_base::error;
2133 }
2134 else if (c1 < 0xE0)
2135 {
2136 if (frm_end-frm_nxt < 2)
2137 return codecvt_base::partial;
2138 uint8_t c2 = frm_nxt[1];
2139 if ((c2 & 0xC0) != 0x80)
2140 return codecvt_base::error;
2141 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2142 | (c2 & 0x3F));
2143 if (t > Maxcode)
2144 return codecvt_base::error;
2145 *to_nxt = t;
2146 frm_nxt += 2;
2147 }
2148 else if (c1 < 0xF0)
2149 {
2150 if (frm_end-frm_nxt < 3)
2151 return codecvt_base::partial;
2152 uint8_t c2 = frm_nxt[1];
2153 uint8_t c3 = frm_nxt[2];
2154 switch (c1)
2155 {
2156 case 0xE0:
2157 if ((c2 & 0xE0) != 0xA0)
2158 return codecvt_base::error;
2159 break;
2160 case 0xED:
2161 if ((c2 & 0xE0) != 0x80)
2162 return codecvt_base::error;
2163 break;
2164 default:
2165 if ((c2 & 0xC0) != 0x80)
2166 return codecvt_base::error;
2167 break;
2168 }
2169 if ((c3 & 0xC0) != 0x80)
2170 return codecvt_base::error;
2171 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2172 | ((c2 & 0x3F) << 6)
2173 | (c3 & 0x3F));
2174 if (t > Maxcode)
2175 return codecvt_base::error;
2176 *to_nxt = t;
2177 frm_nxt += 3;
2178 }
2179 else if (c1 < 0xF5)
2180 {
2181 if (frm_end-frm_nxt < 4)
2182 return codecvt_base::partial;
2183 uint8_t c2 = frm_nxt[1];
2184 uint8_t c3 = frm_nxt[2];
2185 uint8_t c4 = frm_nxt[3];
2186 switch (c1)
2187 {
2188 case 0xF0:
2189 if (!(0x90 <= c2 && c2 <= 0xBF))
2190 return codecvt_base::error;
2191 break;
2192 case 0xF4:
2193 if ((c2 & 0xF0) != 0x80)
2194 return codecvt_base::error;
2195 break;
2196 default:
2197 if ((c2 & 0xC0) != 0x80)
2198 return codecvt_base::error;
2199 break;
2200 }
2201 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2202 return codecvt_base::error;
2203 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2204 | ((c2 & 0x3F) << 12)
2205 | ((c3 & 0x3F) << 6)
2206 | (c4 & 0x3F));
2207 if (t > Maxcode)
2208 return codecvt_base::error;
2209 *to_nxt = t;
2210 frm_nxt += 4;
2211 }
2212 else
2213 {
2214 return codecvt_base::error;
2215 }
2216 }
2217 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2218}
2219
2220static
2221int
2222utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2223 size_t mx, unsigned long Maxcode = 0x10FFFF,
2224 codecvt_mode mode = codecvt_mode(0))
2225{
2226 const uint8_t* frm_nxt = frm;
2227 if (mode & consume_header)
2228 {
2229 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2230 frm_nxt[2] == 0xBF)
2231 frm_nxt += 3;
2232 }
2233 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2234 {
2235 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2236 if (c1 < 0x80)
2237 {
2238 if (c1 > Maxcode)
2239 break;
2240 ++frm_nxt;
2241 }
2242 else if (c1 < 0xC2)
2243 {
2244 break;
2245 }
2246 else if (c1 < 0xE0)
2247 {
2248 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2249 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002250 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002251 break;
2252 frm_nxt += 2;
2253 }
2254 else if (c1 < 0xF0)
2255 {
2256 if (frm_end-frm_nxt < 3)
2257 break;
2258 uint8_t c2 = frm_nxt[1];
2259 uint8_t c3 = frm_nxt[2];
2260 switch (c1)
2261 {
2262 case 0xE0:
2263 if ((c2 & 0xE0) != 0xA0)
2264 return static_cast<int>(frm_nxt - frm);
2265 break;
2266 case 0xED:
2267 if ((c2 & 0xE0) != 0x80)
2268 return static_cast<int>(frm_nxt - frm);
2269 break;
2270 default:
2271 if ((c2 & 0xC0) != 0x80)
2272 return static_cast<int>(frm_nxt - frm);
2273 break;
2274 }
2275 if ((c3 & 0xC0) != 0x80)
2276 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002277 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002278 break;
2279 frm_nxt += 3;
2280 }
2281 else if (c1 < 0xF5)
2282 {
2283 if (frm_end-frm_nxt < 4)
2284 break;
2285 uint8_t c2 = frm_nxt[1];
2286 uint8_t c3 = frm_nxt[2];
2287 uint8_t c4 = frm_nxt[3];
2288 switch (c1)
2289 {
2290 case 0xF0:
2291 if (!(0x90 <= c2 && c2 <= 0xBF))
2292 return static_cast<int>(frm_nxt - frm);
2293 break;
2294 case 0xF4:
2295 if ((c2 & 0xF0) != 0x80)
2296 return static_cast<int>(frm_nxt - frm);
2297 break;
2298 default:
2299 if ((c2 & 0xC0) != 0x80)
2300 return static_cast<int>(frm_nxt - frm);
2301 break;
2302 }
2303 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2304 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002305 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2306 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002307 break;
2308 frm_nxt += 4;
2309 }
2310 else
2311 {
2312 break;
2313 }
2314 }
2315 return static_cast<int>(frm_nxt - frm);
2316}
2317
2318static
2319codecvt_base::result
2320ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2321 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2322 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2323{
2324 frm_nxt = frm;
2325 to_nxt = to;
2326 if (mode & generate_header)
2327 {
2328 if (to_end-to_nxt < 3)
2329 return codecvt_base::partial;
2330 *to_nxt++ = static_cast<uint8_t>(0xEF);
2331 *to_nxt++ = static_cast<uint8_t>(0xBB);
2332 *to_nxt++ = static_cast<uint8_t>(0xBF);
2333 }
2334 for (; frm_nxt < frm_end; ++frm_nxt)
2335 {
2336 uint16_t wc = *frm_nxt;
2337 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2338 return codecvt_base::error;
2339 if (wc < 0x0080)
2340 {
2341 if (to_end-to_nxt < 1)
2342 return codecvt_base::partial;
2343 *to_nxt++ = static_cast<uint8_t>(wc);
2344 }
2345 else if (wc < 0x0800)
2346 {
2347 if (to_end-to_nxt < 2)
2348 return codecvt_base::partial;
2349 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2350 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2351 }
2352 else // if (wc <= 0xFFFF)
2353 {
2354 if (to_end-to_nxt < 3)
2355 return codecvt_base::partial;
2356 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2357 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2358 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2359 }
2360 }
2361 return codecvt_base::ok;
2362}
2363
2364static
2365codecvt_base::result
2366utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2367 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2368 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2369{
2370 frm_nxt = frm;
2371 to_nxt = to;
2372 if (mode & consume_header)
2373 {
2374 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2375 frm_nxt[2] == 0xBF)
2376 frm_nxt += 3;
2377 }
2378 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2379 {
2380 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2381 if (c1 < 0x80)
2382 {
2383 if (c1 > Maxcode)
2384 return codecvt_base::error;
2385 *to_nxt = static_cast<uint16_t>(c1);
2386 ++frm_nxt;
2387 }
2388 else if (c1 < 0xC2)
2389 {
2390 return codecvt_base::error;
2391 }
2392 else if (c1 < 0xE0)
2393 {
2394 if (frm_end-frm_nxt < 2)
2395 return codecvt_base::partial;
2396 uint8_t c2 = frm_nxt[1];
2397 if ((c2 & 0xC0) != 0x80)
2398 return codecvt_base::error;
2399 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2400 | (c2 & 0x3F));
2401 if (t > Maxcode)
2402 return codecvt_base::error;
2403 *to_nxt = t;
2404 frm_nxt += 2;
2405 }
2406 else if (c1 < 0xF0)
2407 {
2408 if (frm_end-frm_nxt < 3)
2409 return codecvt_base::partial;
2410 uint8_t c2 = frm_nxt[1];
2411 uint8_t c3 = frm_nxt[2];
2412 switch (c1)
2413 {
2414 case 0xE0:
2415 if ((c2 & 0xE0) != 0xA0)
2416 return codecvt_base::error;
2417 break;
2418 case 0xED:
2419 if ((c2 & 0xE0) != 0x80)
2420 return codecvt_base::error;
2421 break;
2422 default:
2423 if ((c2 & 0xC0) != 0x80)
2424 return codecvt_base::error;
2425 break;
2426 }
2427 if ((c3 & 0xC0) != 0x80)
2428 return codecvt_base::error;
2429 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2430 | ((c2 & 0x3F) << 6)
2431 | (c3 & 0x3F));
2432 if (t > Maxcode)
2433 return codecvt_base::error;
2434 *to_nxt = t;
2435 frm_nxt += 3;
2436 }
2437 else
2438 {
2439 return codecvt_base::error;
2440 }
2441 }
2442 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2443}
2444
2445static
2446int
2447utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2448 size_t mx, unsigned long Maxcode = 0x10FFFF,
2449 codecvt_mode mode = codecvt_mode(0))
2450{
2451 const uint8_t* frm_nxt = frm;
2452 if (mode & consume_header)
2453 {
2454 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2455 frm_nxt[2] == 0xBF)
2456 frm_nxt += 3;
2457 }
2458 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2459 {
2460 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2461 if (c1 < 0x80)
2462 {
2463 if (c1 > Maxcode)
2464 break;
2465 ++frm_nxt;
2466 }
2467 else if (c1 < 0xC2)
2468 {
2469 break;
2470 }
2471 else if (c1 < 0xE0)
2472 {
2473 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2474 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002475 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002476 break;
2477 frm_nxt += 2;
2478 }
2479 else if (c1 < 0xF0)
2480 {
2481 if (frm_end-frm_nxt < 3)
2482 break;
2483 uint8_t c2 = frm_nxt[1];
2484 uint8_t c3 = frm_nxt[2];
2485 switch (c1)
2486 {
2487 case 0xE0:
2488 if ((c2 & 0xE0) != 0xA0)
2489 return static_cast<int>(frm_nxt - frm);
2490 break;
2491 case 0xED:
2492 if ((c2 & 0xE0) != 0x80)
2493 return static_cast<int>(frm_nxt - frm);
2494 break;
2495 default:
2496 if ((c2 & 0xC0) != 0x80)
2497 return static_cast<int>(frm_nxt - frm);
2498 break;
2499 }
2500 if ((c3 & 0xC0) != 0x80)
2501 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002502 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002503 break;
2504 frm_nxt += 3;
2505 }
2506 else
2507 {
2508 break;
2509 }
2510 }
2511 return static_cast<int>(frm_nxt - frm);
2512}
2513
2514static
2515codecvt_base::result
2516ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2517 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2518 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2519{
2520 frm_nxt = frm;
2521 to_nxt = to;
2522 if (mode & generate_header)
2523 {
2524 if (to_end-to_nxt < 2)
2525 return codecvt_base::partial;
2526 *to_nxt++ = static_cast<uint8_t>(0xFE);
2527 *to_nxt++ = static_cast<uint8_t>(0xFF);
2528 }
2529 for (; frm_nxt < frm_end; ++frm_nxt)
2530 {
2531 uint32_t wc = *frm_nxt;
2532 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2533 return codecvt_base::error;
2534 if (wc < 0x010000)
2535 {
2536 if (to_end-to_nxt < 2)
2537 return codecvt_base::partial;
2538 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2539 *to_nxt++ = static_cast<uint8_t>(wc);
2540 }
2541 else
2542 {
2543 if (to_end-to_nxt < 4)
2544 return codecvt_base::partial;
2545 uint16_t t = static_cast<uint16_t>(
2546 0xD800
2547 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2548 | ((wc & 0x00FC00) >> 10));
2549 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2550 *to_nxt++ = static_cast<uint8_t>(t);
2551 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2552 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2553 *to_nxt++ = static_cast<uint8_t>(t);
2554 }
2555 }
2556 return codecvt_base::ok;
2557}
2558
2559static
2560codecvt_base::result
2561utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2562 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2563 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2564{
2565 frm_nxt = frm;
2566 to_nxt = to;
2567 if (mode & consume_header)
2568 {
2569 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2570 frm_nxt += 2;
2571 }
2572 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2573 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002574 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002575 if ((c1 & 0xFC00) == 0xDC00)
2576 return codecvt_base::error;
2577 if ((c1 & 0xFC00) != 0xD800)
2578 {
2579 if (c1 > Maxcode)
2580 return codecvt_base::error;
2581 *to_nxt = static_cast<uint32_t>(c1);
2582 frm_nxt += 2;
2583 }
2584 else
2585 {
2586 if (frm_end-frm_nxt < 4)
2587 return codecvt_base::partial;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002588 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002589 if ((c2 & 0xFC00) != 0xDC00)
2590 return codecvt_base::error;
2591 uint32_t t = static_cast<uint32_t>(
2592 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2593 | ((c1 & 0x003F) << 10)
2594 | (c2 & 0x03FF));
2595 if (t > Maxcode)
2596 return codecvt_base::error;
2597 *to_nxt = t;
2598 frm_nxt += 4;
2599 }
2600 }
2601 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2602}
2603
2604static
2605int
2606utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2607 size_t mx, unsigned long Maxcode = 0x10FFFF,
2608 codecvt_mode mode = codecvt_mode(0))
2609{
2610 const uint8_t* frm_nxt = frm;
2611 frm_nxt = frm;
2612 if (mode & consume_header)
2613 {
2614 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2615 frm_nxt += 2;
2616 }
2617 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2618 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002619 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002620 if ((c1 & 0xFC00) == 0xDC00)
2621 break;
2622 if ((c1 & 0xFC00) != 0xD800)
2623 {
2624 if (c1 > Maxcode)
2625 break;
2626 frm_nxt += 2;
2627 }
2628 else
2629 {
2630 if (frm_end-frm_nxt < 4)
2631 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002632 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002633 if ((c2 & 0xFC00) != 0xDC00)
2634 break;
2635 uint32_t t = static_cast<uint32_t>(
2636 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2637 | ((c1 & 0x003F) << 10)
2638 | (c2 & 0x03FF));
2639 if (t > Maxcode)
2640 break;
2641 frm_nxt += 4;
2642 }
2643 }
2644 return static_cast<int>(frm_nxt - frm);
2645}
2646
2647static
2648codecvt_base::result
2649ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2650 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2651 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2652{
2653 frm_nxt = frm;
2654 to_nxt = to;
2655 if (mode & generate_header)
2656 {
2657 if (to_end-to_nxt < 2)
2658 return codecvt_base::partial;
2659 *to_nxt++ = static_cast<uint8_t>(0xFF);
2660 *to_nxt++ = static_cast<uint8_t>(0xFE);
2661 }
2662 for (; frm_nxt < frm_end; ++frm_nxt)
2663 {
2664 uint32_t wc = *frm_nxt;
2665 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2666 return codecvt_base::error;
2667 if (wc < 0x010000)
2668 {
2669 if (to_end-to_nxt < 2)
2670 return codecvt_base::partial;
2671 *to_nxt++ = static_cast<uint8_t>(wc);
2672 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2673 }
2674 else
2675 {
2676 if (to_end-to_nxt < 4)
2677 return codecvt_base::partial;
2678 uint16_t t = static_cast<uint16_t>(
2679 0xD800
2680 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2681 | ((wc & 0x00FC00) >> 10));
2682 *to_nxt++ = static_cast<uint8_t>(t);
2683 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2684 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2685 *to_nxt++ = static_cast<uint8_t>(t);
2686 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2687 }
2688 }
2689 return codecvt_base::ok;
2690}
2691
2692static
2693codecvt_base::result
2694utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2695 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2696 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2697{
2698 frm_nxt = frm;
2699 to_nxt = to;
2700 if (mode & consume_header)
2701 {
2702 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2703 frm_nxt += 2;
2704 }
2705 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2706 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002707 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002708 if ((c1 & 0xFC00) == 0xDC00)
2709 return codecvt_base::error;
2710 if ((c1 & 0xFC00) != 0xD800)
2711 {
2712 if (c1 > Maxcode)
2713 return codecvt_base::error;
2714 *to_nxt = static_cast<uint32_t>(c1);
2715 frm_nxt += 2;
2716 }
2717 else
2718 {
2719 if (frm_end-frm_nxt < 4)
2720 return codecvt_base::partial;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002721 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002722 if ((c2 & 0xFC00) != 0xDC00)
2723 return codecvt_base::error;
2724 uint32_t t = static_cast<uint32_t>(
2725 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2726 | ((c1 & 0x003F) << 10)
2727 | (c2 & 0x03FF));
2728 if (t > Maxcode)
2729 return codecvt_base::error;
2730 *to_nxt = t;
2731 frm_nxt += 4;
2732 }
2733 }
2734 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2735}
2736
2737static
2738int
2739utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2740 size_t mx, unsigned long Maxcode = 0x10FFFF,
2741 codecvt_mode mode = codecvt_mode(0))
2742{
2743 const uint8_t* frm_nxt = frm;
2744 frm_nxt = frm;
2745 if (mode & consume_header)
2746 {
2747 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2748 frm_nxt += 2;
2749 }
2750 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2751 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002752 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002753 if ((c1 & 0xFC00) == 0xDC00)
2754 break;
2755 if ((c1 & 0xFC00) != 0xD800)
2756 {
2757 if (c1 > Maxcode)
2758 break;
2759 frm_nxt += 2;
2760 }
2761 else
2762 {
2763 if (frm_end-frm_nxt < 4)
2764 break;
Howard Hinnantec3773c2011-12-01 20:21:04 +00002765 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002766 if ((c2 & 0xFC00) != 0xDC00)
2767 break;
2768 uint32_t t = static_cast<uint32_t>(
2769 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2770 | ((c1 & 0x003F) << 10)
2771 | (c2 & 0x03FF));
2772 if (t > Maxcode)
2773 break;
2774 frm_nxt += 4;
2775 }
2776 }
2777 return static_cast<int>(frm_nxt - frm);
2778}
2779
2780static
2781codecvt_base::result
2782ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2783 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2784 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2785{
2786 frm_nxt = frm;
2787 to_nxt = to;
2788 if (mode & generate_header)
2789 {
2790 if (to_end-to_nxt < 2)
2791 return codecvt_base::partial;
2792 *to_nxt++ = static_cast<uint8_t>(0xFE);
2793 *to_nxt++ = static_cast<uint8_t>(0xFF);
2794 }
2795 for (; frm_nxt < frm_end; ++frm_nxt)
2796 {
2797 uint16_t wc = *frm_nxt;
2798 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2799 return codecvt_base::error;
2800 if (to_end-to_nxt < 2)
2801 return codecvt_base::partial;
2802 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2803 *to_nxt++ = static_cast<uint8_t>(wc);
2804 }
2805 return codecvt_base::ok;
2806}
2807
2808static
2809codecvt_base::result
2810utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2811 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2812 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2813{
2814 frm_nxt = frm;
2815 to_nxt = to;
2816 if (mode & consume_header)
2817 {
2818 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2819 frm_nxt += 2;
2820 }
2821 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2822 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002823 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002824 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2825 return codecvt_base::error;
2826 *to_nxt = c1;
2827 frm_nxt += 2;
2828 }
2829 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2830}
2831
2832static
2833int
2834utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2835 size_t mx, unsigned long Maxcode = 0x10FFFF,
2836 codecvt_mode mode = codecvt_mode(0))
2837{
2838 const uint8_t* frm_nxt = frm;
2839 frm_nxt = frm;
2840 if (mode & consume_header)
2841 {
2842 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2843 frm_nxt += 2;
2844 }
2845 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2846 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002847 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002848 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2849 break;
2850 frm_nxt += 2;
2851 }
2852 return static_cast<int>(frm_nxt - frm);
2853}
2854
2855static
2856codecvt_base::result
2857ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2858 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2859 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2860{
2861 frm_nxt = frm;
2862 to_nxt = to;
2863 if (mode & generate_header)
2864 {
2865 if (to_end-to_nxt < 2)
2866 return codecvt_base::partial;
2867 *to_nxt++ = static_cast<uint8_t>(0xFF);
2868 *to_nxt++ = static_cast<uint8_t>(0xFE);
2869 }
2870 for (; frm_nxt < frm_end; ++frm_nxt)
2871 {
2872 uint16_t wc = *frm_nxt;
2873 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2874 return codecvt_base::error;
2875 if (to_end-to_nxt < 2)
2876 return codecvt_base::partial;
2877 *to_nxt++ = static_cast<uint8_t>(wc);
2878 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2879 }
2880 return codecvt_base::ok;
2881}
2882
2883static
2884codecvt_base::result
2885utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2886 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2887 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2888{
2889 frm_nxt = frm;
2890 to_nxt = to;
2891 if (mode & consume_header)
2892 {
2893 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2894 frm_nxt += 2;
2895 }
2896 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2897 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002898 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002899 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2900 return codecvt_base::error;
2901 *to_nxt = c1;
2902 frm_nxt += 2;
2903 }
2904 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2905}
2906
2907static
2908int
2909utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2910 size_t mx, unsigned long Maxcode = 0x10FFFF,
2911 codecvt_mode mode = codecvt_mode(0))
2912{
2913 const uint8_t* frm_nxt = frm;
2914 frm_nxt = frm;
2915 if (mode & consume_header)
2916 {
2917 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2918 frm_nxt += 2;
2919 }
2920 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2921 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00002922 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002923 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2924 break;
2925 frm_nxt += 2;
2926 }
2927 return static_cast<int>(frm_nxt - frm);
2928}
2929
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002930// template <> class codecvt<char16_t, char, mbstate_t>
2931
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002932locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002933
2934codecvt<char16_t, char, mbstate_t>::~codecvt()
2935{
2936}
2937
2938codecvt<char16_t, char, mbstate_t>::result
2939codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002940 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002941 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2942{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002943 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2944 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2945 const uint16_t* _frm_nxt = _frm;
2946 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2947 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2948 uint8_t* _to_nxt = _to;
2949 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2950 frm_nxt = frm + (_frm_nxt - _frm);
2951 to_nxt = to + (_to_nxt - _to);
2952 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002953}
2954
2955codecvt<char16_t, char, mbstate_t>::result
2956codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00002957 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002958 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2959{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002960 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2961 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2962 const uint8_t* _frm_nxt = _frm;
2963 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2964 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2965 uint16_t* _to_nxt = _to;
2966 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2967 frm_nxt = frm + (_frm_nxt - _frm);
2968 to_nxt = to + (_to_nxt - _to);
2969 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002970}
2971
2972codecvt<char16_t, char, mbstate_t>::result
2973codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2974 extern_type* to, extern_type*, extern_type*& to_nxt) const
2975{
2976 to_nxt = to;
2977 return noconv;
2978}
2979
2980int
Howard Hinnantc9834542011-05-31 15:34:58 +00002981codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002982{
2983 return 0;
2984}
2985
2986bool
Howard Hinnantc9834542011-05-31 15:34:58 +00002987codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002988{
2989 return false;
2990}
2991
2992int
2993codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2994 const extern_type* frm, const extern_type* frm_end, size_t mx) const
2995{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00002996 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2997 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2998 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002999}
3000
3001int
Howard Hinnantc9834542011-05-31 15:34:58 +00003002codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003003{
3004 return 4;
3005}
3006
3007// template <> class codecvt<char32_t, char, mbstate_t>
3008
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003009locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003010
3011codecvt<char32_t, char, mbstate_t>::~codecvt()
3012{
3013}
3014
3015codecvt<char32_t, char, mbstate_t>::result
3016codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003017 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003018 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3019{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003020 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3021 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3022 const uint32_t* _frm_nxt = _frm;
3023 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3024 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3025 uint8_t* _to_nxt = _to;
3026 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3027 frm_nxt = frm + (_frm_nxt - _frm);
3028 to_nxt = to + (_to_nxt - _to);
3029 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003030}
3031
3032codecvt<char32_t, char, mbstate_t>::result
3033codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00003034 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003035 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3036{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003037 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3038 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3039 const uint8_t* _frm_nxt = _frm;
3040 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3041 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3042 uint32_t* _to_nxt = _to;
3043 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3044 frm_nxt = frm + (_frm_nxt - _frm);
3045 to_nxt = to + (_to_nxt - _to);
3046 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003047}
3048
3049codecvt<char32_t, char, mbstate_t>::result
3050codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3051 extern_type* to, extern_type*, extern_type*& to_nxt) const
3052{
3053 to_nxt = to;
3054 return noconv;
3055}
3056
3057int
Howard Hinnantc9834542011-05-31 15:34:58 +00003058codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003059{
3060 return 0;
3061}
3062
3063bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003064codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003065{
3066 return false;
3067}
3068
3069int
3070codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3071 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3072{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003073 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3074 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3075 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003076}
3077
3078int
Howard Hinnantc9834542011-05-31 15:34:58 +00003079codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003080{
3081 return 4;
3082}
3083
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003084// __codecvt_utf8<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003085
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003086__codecvt_utf8<wchar_t>::result
3087__codecvt_utf8<wchar_t>::do_out(state_type&,
3088 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003089 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3090{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003091 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3092 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3093 const uint32_t* _frm_nxt = _frm;
3094 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3095 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3096 uint8_t* _to_nxt = _to;
3097 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3098 _Maxcode_, _Mode_);
3099 frm_nxt = frm + (_frm_nxt - _frm);
3100 to_nxt = to + (_to_nxt - _to);
3101 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003102}
3103
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003104__codecvt_utf8<wchar_t>::result
3105__codecvt_utf8<wchar_t>::do_in(state_type&,
3106 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003107 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3108{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003109 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3110 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3111 const uint8_t* _frm_nxt = _frm;
3112 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3113 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3114 uint32_t* _to_nxt = _to;
3115 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3116 _Maxcode_, _Mode_);
3117 frm_nxt = frm + (_frm_nxt - _frm);
3118 to_nxt = to + (_to_nxt - _to);
3119 return r;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003120}
3121
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003122__codecvt_utf8<wchar_t>::result
3123__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003124 extern_type* to, extern_type*, extern_type*& to_nxt) const
3125{
3126 to_nxt = to;
3127 return noconv;
3128}
3129
3130int
Howard Hinnantc9834542011-05-31 15:34:58 +00003131__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003132{
3133 return 0;
3134}
3135
3136bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003137__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003138{
3139 return false;
3140}
3141
3142int
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003143__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003144 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3145{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003146 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3147 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3148 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003149}
3150
3151int
Howard Hinnantc9834542011-05-31 15:34:58 +00003152__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003153{
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003154 if (_Mode_ & consume_header)
3155 return 7;
3156 return 4;
3157}
3158
3159// __codecvt_utf8<char16_t>
3160
3161__codecvt_utf8<char16_t>::result
3162__codecvt_utf8<char16_t>::do_out(state_type&,
3163 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3164 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3165{
3166 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3167 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3168 const uint16_t* _frm_nxt = _frm;
3169 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3170 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3171 uint8_t* _to_nxt = _to;
3172 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3173 _Maxcode_, _Mode_);
3174 frm_nxt = frm + (_frm_nxt - _frm);
3175 to_nxt = to + (_to_nxt - _to);
3176 return r;
3177}
3178
3179__codecvt_utf8<char16_t>::result
3180__codecvt_utf8<char16_t>::do_in(state_type&,
3181 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3182 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3183{
3184 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3185 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3186 const uint8_t* _frm_nxt = _frm;
3187 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3188 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3189 uint16_t* _to_nxt = _to;
3190 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3191 _Maxcode_, _Mode_);
3192 frm_nxt = frm + (_frm_nxt - _frm);
3193 to_nxt = to + (_to_nxt - _to);
3194 return r;
3195}
3196
3197__codecvt_utf8<char16_t>::result
3198__codecvt_utf8<char16_t>::do_unshift(state_type&,
3199 extern_type* to, extern_type*, extern_type*& to_nxt) const
3200{
3201 to_nxt = to;
3202 return noconv;
3203}
3204
3205int
Howard Hinnantc9834542011-05-31 15:34:58 +00003206__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003207{
3208 return 0;
3209}
3210
3211bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003212__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003213{
3214 return false;
3215}
3216
3217int
3218__codecvt_utf8<char16_t>::do_length(state_type&,
3219 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3220{
3221 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3222 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3223 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3224}
3225
3226int
Howard Hinnantc9834542011-05-31 15:34:58 +00003227__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003228{
3229 if (_Mode_ & consume_header)
3230 return 6;
3231 return 3;
3232}
3233
3234// __codecvt_utf8<char32_t>
3235
3236__codecvt_utf8<char32_t>::result
3237__codecvt_utf8<char32_t>::do_out(state_type&,
3238 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3239 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3240{
3241 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3242 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3243 const uint32_t* _frm_nxt = _frm;
3244 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3245 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3246 uint8_t* _to_nxt = _to;
3247 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3248 _Maxcode_, _Mode_);
3249 frm_nxt = frm + (_frm_nxt - _frm);
3250 to_nxt = to + (_to_nxt - _to);
3251 return r;
3252}
3253
3254__codecvt_utf8<char32_t>::result
3255__codecvt_utf8<char32_t>::do_in(state_type&,
3256 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3257 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3258{
3259 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3260 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3261 const uint8_t* _frm_nxt = _frm;
3262 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3263 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3264 uint32_t* _to_nxt = _to;
3265 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3266 _Maxcode_, _Mode_);
3267 frm_nxt = frm + (_frm_nxt - _frm);
3268 to_nxt = to + (_to_nxt - _to);
3269 return r;
3270}
3271
3272__codecvt_utf8<char32_t>::result
3273__codecvt_utf8<char32_t>::do_unshift(state_type&,
3274 extern_type* to, extern_type*, extern_type*& to_nxt) const
3275{
3276 to_nxt = to;
3277 return noconv;
3278}
3279
3280int
Howard Hinnantc9834542011-05-31 15:34:58 +00003281__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003282{
3283 return 0;
3284}
3285
3286bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003287__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003288{
3289 return false;
3290}
3291
3292int
3293__codecvt_utf8<char32_t>::do_length(state_type&,
3294 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3295{
3296 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3297 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3298 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3299}
3300
3301int
Howard Hinnantc9834542011-05-31 15:34:58 +00003302__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003303{
3304 if (_Mode_ & consume_header)
3305 return 7;
3306 return 4;
3307}
3308
3309// __codecvt_utf16<wchar_t, false>
3310
3311__codecvt_utf16<wchar_t, false>::result
3312__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3313 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3314 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3315{
3316 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3317 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3318 const uint32_t* _frm_nxt = _frm;
3319 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3320 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3321 uint8_t* _to_nxt = _to;
3322 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3323 _Maxcode_, _Mode_);
3324 frm_nxt = frm + (_frm_nxt - _frm);
3325 to_nxt = to + (_to_nxt - _to);
3326 return r;
3327}
3328
3329__codecvt_utf16<wchar_t, false>::result
3330__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3331 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3332 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3333{
3334 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3335 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3336 const uint8_t* _frm_nxt = _frm;
3337 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3338 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3339 uint32_t* _to_nxt = _to;
3340 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3341 _Maxcode_, _Mode_);
3342 frm_nxt = frm + (_frm_nxt - _frm);
3343 to_nxt = to + (_to_nxt - _to);
3344 return r;
3345}
3346
3347__codecvt_utf16<wchar_t, false>::result
3348__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3349 extern_type* to, extern_type*, extern_type*& to_nxt) const
3350{
3351 to_nxt = to;
3352 return noconv;
3353}
3354
3355int
Howard Hinnantc9834542011-05-31 15:34:58 +00003356__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003357{
3358 return 0;
3359}
3360
3361bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003362__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003363{
3364 return false;
3365}
3366
3367int
3368__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3369 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3370{
3371 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3372 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3373 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3374}
3375
3376int
Howard Hinnantc9834542011-05-31 15:34:58 +00003377__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003378{
3379 if (_Mode_ & consume_header)
3380 return 6;
3381 return 4;
3382}
3383
3384// __codecvt_utf16<wchar_t, true>
3385
3386__codecvt_utf16<wchar_t, true>::result
3387__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3388 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3389 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3390{
3391 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3392 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3393 const uint32_t* _frm_nxt = _frm;
3394 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3395 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3396 uint8_t* _to_nxt = _to;
3397 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3398 _Maxcode_, _Mode_);
3399 frm_nxt = frm + (_frm_nxt - _frm);
3400 to_nxt = to + (_to_nxt - _to);
3401 return r;
3402}
3403
3404__codecvt_utf16<wchar_t, true>::result
3405__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3406 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3407 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3408{
3409 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3410 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3411 const uint8_t* _frm_nxt = _frm;
3412 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3413 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3414 uint32_t* _to_nxt = _to;
3415 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3416 _Maxcode_, _Mode_);
3417 frm_nxt = frm + (_frm_nxt - _frm);
3418 to_nxt = to + (_to_nxt - _to);
3419 return r;
3420}
3421
3422__codecvt_utf16<wchar_t, true>::result
3423__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3424 extern_type* to, extern_type*, extern_type*& to_nxt) const
3425{
3426 to_nxt = to;
3427 return noconv;
3428}
3429
3430int
Howard Hinnantc9834542011-05-31 15:34:58 +00003431__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003432{
3433 return 0;
3434}
3435
3436bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003437__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003438{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003439 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003440}
3441
3442int
3443__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3444 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3445{
3446 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3447 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3448 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3449}
3450
3451int
Howard Hinnantc9834542011-05-31 15:34:58 +00003452__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003453{
3454 if (_Mode_ & consume_header)
3455 return 6;
3456 return 4;
3457}
3458
3459// __codecvt_utf16<char16_t, false>
3460
3461__codecvt_utf16<char16_t, false>::result
3462__codecvt_utf16<char16_t, false>::do_out(state_type&,
3463 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3464 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3465{
3466 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3467 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3468 const uint16_t* _frm_nxt = _frm;
3469 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3470 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3471 uint8_t* _to_nxt = _to;
3472 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3473 _Maxcode_, _Mode_);
3474 frm_nxt = frm + (_frm_nxt - _frm);
3475 to_nxt = to + (_to_nxt - _to);
3476 return r;
3477}
3478
3479__codecvt_utf16<char16_t, false>::result
3480__codecvt_utf16<char16_t, false>::do_in(state_type&,
3481 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3482 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3483{
3484 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3485 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3486 const uint8_t* _frm_nxt = _frm;
3487 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3488 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3489 uint16_t* _to_nxt = _to;
3490 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3491 _Maxcode_, _Mode_);
3492 frm_nxt = frm + (_frm_nxt - _frm);
3493 to_nxt = to + (_to_nxt - _to);
3494 return r;
3495}
3496
3497__codecvt_utf16<char16_t, false>::result
3498__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3499 extern_type* to, extern_type*, extern_type*& to_nxt) const
3500{
3501 to_nxt = to;
3502 return noconv;
3503}
3504
3505int
Howard Hinnantc9834542011-05-31 15:34:58 +00003506__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003507{
3508 return 0;
3509}
3510
3511bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003512__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003513{
3514 return false;
3515}
3516
3517int
3518__codecvt_utf16<char16_t, false>::do_length(state_type&,
3519 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3520{
3521 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3522 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3523 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3524}
3525
3526int
Howard Hinnantc9834542011-05-31 15:34:58 +00003527__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003528{
3529 if (_Mode_ & consume_header)
3530 return 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003531 return 2;
3532}
3533
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003534// __codecvt_utf16<char16_t, true>
3535
3536__codecvt_utf16<char16_t, true>::result
3537__codecvt_utf16<char16_t, true>::do_out(state_type&,
3538 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3539 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3540{
3541 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3542 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3543 const uint16_t* _frm_nxt = _frm;
3544 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3545 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3546 uint8_t* _to_nxt = _to;
3547 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3548 _Maxcode_, _Mode_);
3549 frm_nxt = frm + (_frm_nxt - _frm);
3550 to_nxt = to + (_to_nxt - _to);
3551 return r;
3552}
3553
3554__codecvt_utf16<char16_t, true>::result
3555__codecvt_utf16<char16_t, true>::do_in(state_type&,
3556 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3557 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3558{
3559 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3560 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3561 const uint8_t* _frm_nxt = _frm;
3562 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3563 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3564 uint16_t* _to_nxt = _to;
3565 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3566 _Maxcode_, _Mode_);
3567 frm_nxt = frm + (_frm_nxt - _frm);
3568 to_nxt = to + (_to_nxt - _to);
3569 return r;
3570}
3571
3572__codecvt_utf16<char16_t, true>::result
3573__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3574 extern_type* to, extern_type*, extern_type*& to_nxt) const
3575{
3576 to_nxt = to;
3577 return noconv;
3578}
3579
3580int
Howard Hinnantc9834542011-05-31 15:34:58 +00003581__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003582{
3583 return 0;
3584}
3585
3586bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003587__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003588{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003589 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003590}
3591
3592int
3593__codecvt_utf16<char16_t, true>::do_length(state_type&,
3594 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3595{
3596 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3597 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3598 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3599}
3600
3601int
Howard Hinnantc9834542011-05-31 15:34:58 +00003602__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003603{
3604 if (_Mode_ & consume_header)
3605 return 4;
3606 return 2;
3607}
3608
3609// __codecvt_utf16<char32_t, false>
3610
3611__codecvt_utf16<char32_t, false>::result
3612__codecvt_utf16<char32_t, false>::do_out(state_type&,
3613 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3614 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3615{
3616 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3617 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3618 const uint32_t* _frm_nxt = _frm;
3619 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3620 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3621 uint8_t* _to_nxt = _to;
3622 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3623 _Maxcode_, _Mode_);
3624 frm_nxt = frm + (_frm_nxt - _frm);
3625 to_nxt = to + (_to_nxt - _to);
3626 return r;
3627}
3628
3629__codecvt_utf16<char32_t, false>::result
3630__codecvt_utf16<char32_t, false>::do_in(state_type&,
3631 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3632 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3633{
3634 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3635 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3636 const uint8_t* _frm_nxt = _frm;
3637 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3638 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3639 uint32_t* _to_nxt = _to;
3640 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3641 _Maxcode_, _Mode_);
3642 frm_nxt = frm + (_frm_nxt - _frm);
3643 to_nxt = to + (_to_nxt - _to);
3644 return r;
3645}
3646
3647__codecvt_utf16<char32_t, false>::result
3648__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3649 extern_type* to, extern_type*, extern_type*& to_nxt) const
3650{
3651 to_nxt = to;
3652 return noconv;
3653}
3654
3655int
Howard Hinnantc9834542011-05-31 15:34:58 +00003656__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003657{
3658 return 0;
3659}
3660
3661bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003662__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003663{
3664 return false;
3665}
3666
3667int
3668__codecvt_utf16<char32_t, false>::do_length(state_type&,
3669 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3670{
3671 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3672 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3673 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3674}
3675
3676int
Howard Hinnantc9834542011-05-31 15:34:58 +00003677__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003678{
3679 if (_Mode_ & consume_header)
3680 return 6;
3681 return 4;
3682}
3683
3684// __codecvt_utf16<char32_t, true>
3685
3686__codecvt_utf16<char32_t, true>::result
3687__codecvt_utf16<char32_t, true>::do_out(state_type&,
3688 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3689 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3690{
3691 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3692 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3693 const uint32_t* _frm_nxt = _frm;
3694 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3695 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3696 uint8_t* _to_nxt = _to;
3697 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3698 _Maxcode_, _Mode_);
3699 frm_nxt = frm + (_frm_nxt - _frm);
3700 to_nxt = to + (_to_nxt - _to);
3701 return r;
3702}
3703
3704__codecvt_utf16<char32_t, true>::result
3705__codecvt_utf16<char32_t, true>::do_in(state_type&,
3706 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3707 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3708{
3709 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3710 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3711 const uint8_t* _frm_nxt = _frm;
3712 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3713 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3714 uint32_t* _to_nxt = _to;
3715 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3716 _Maxcode_, _Mode_);
3717 frm_nxt = frm + (_frm_nxt - _frm);
3718 to_nxt = to + (_to_nxt - _to);
3719 return r;
3720}
3721
3722__codecvt_utf16<char32_t, true>::result
3723__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3724 extern_type* to, extern_type*, extern_type*& to_nxt) const
3725{
3726 to_nxt = to;
3727 return noconv;
3728}
3729
3730int
Howard Hinnantc9834542011-05-31 15:34:58 +00003731__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003732{
3733 return 0;
3734}
3735
3736bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003737__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003738{
Howard Hinnantd23b4642010-05-31 20:58:54 +00003739 return false;
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003740}
3741
3742int
3743__codecvt_utf16<char32_t, true>::do_length(state_type&,
3744 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3745{
3746 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3747 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3748 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3749}
3750
3751int
Howard Hinnantc9834542011-05-31 15:34:58 +00003752__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003753{
3754 if (_Mode_ & consume_header)
3755 return 6;
3756 return 4;
3757}
3758
3759// __codecvt_utf8_utf16<wchar_t>
3760
3761__codecvt_utf8_utf16<wchar_t>::result
3762__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3763 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3764 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3765{
3766 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3767 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3768 const uint32_t* _frm_nxt = _frm;
3769 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3770 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3771 uint8_t* _to_nxt = _to;
3772 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3773 _Maxcode_, _Mode_);
3774 frm_nxt = frm + (_frm_nxt - _frm);
3775 to_nxt = to + (_to_nxt - _to);
3776 return r;
3777}
3778
3779__codecvt_utf8_utf16<wchar_t>::result
3780__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3781 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3782 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3783{
3784 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3785 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3786 const uint8_t* _frm_nxt = _frm;
3787 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3788 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3789 uint32_t* _to_nxt = _to;
3790 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3791 _Maxcode_, _Mode_);
3792 frm_nxt = frm + (_frm_nxt - _frm);
3793 to_nxt = to + (_to_nxt - _to);
3794 return r;
3795}
3796
3797__codecvt_utf8_utf16<wchar_t>::result
3798__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3799 extern_type* to, extern_type*, extern_type*& to_nxt) const
3800{
3801 to_nxt = to;
3802 return noconv;
3803}
3804
3805int
Howard Hinnantc9834542011-05-31 15:34:58 +00003806__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003807{
3808 return 0;
3809}
3810
3811bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003812__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003813{
3814 return false;
3815}
3816
3817int
3818__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3819 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3820{
3821 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3822 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3823 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3824}
3825
3826int
Howard Hinnantc9834542011-05-31 15:34:58 +00003827__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003828{
3829 if (_Mode_ & consume_header)
3830 return 7;
3831 return 4;
3832}
3833
3834// __codecvt_utf8_utf16<char16_t>
3835
3836__codecvt_utf8_utf16<char16_t>::result
3837__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3838 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3839 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3840{
3841 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3842 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3843 const uint16_t* _frm_nxt = _frm;
3844 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3845 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3846 uint8_t* _to_nxt = _to;
3847 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3848 _Maxcode_, _Mode_);
3849 frm_nxt = frm + (_frm_nxt - _frm);
3850 to_nxt = to + (_to_nxt - _to);
3851 return r;
3852}
3853
3854__codecvt_utf8_utf16<char16_t>::result
3855__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3856 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3857 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3858{
3859 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3860 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3861 const uint8_t* _frm_nxt = _frm;
3862 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3863 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3864 uint16_t* _to_nxt = _to;
3865 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3866 _Maxcode_, _Mode_);
3867 frm_nxt = frm + (_frm_nxt - _frm);
3868 to_nxt = to + (_to_nxt - _to);
3869 return r;
3870}
3871
3872__codecvt_utf8_utf16<char16_t>::result
3873__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3874 extern_type* to, extern_type*, extern_type*& to_nxt) const
3875{
3876 to_nxt = to;
3877 return noconv;
3878}
3879
3880int
Howard Hinnantc9834542011-05-31 15:34:58 +00003881__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003882{
3883 return 0;
3884}
3885
3886bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003887__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003888{
3889 return false;
3890}
3891
3892int
3893__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3894 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3895{
3896 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3897 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3898 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3899}
3900
3901int
Howard Hinnantc9834542011-05-31 15:34:58 +00003902__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003903{
3904 if (_Mode_ & consume_header)
3905 return 7;
3906 return 4;
3907}
3908
3909// __codecvt_utf8_utf16<char32_t>
3910
3911__codecvt_utf8_utf16<char32_t>::result
3912__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3913 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3914 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3915{
3916 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3917 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3918 const uint32_t* _frm_nxt = _frm;
3919 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3920 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3921 uint8_t* _to_nxt = _to;
3922 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3923 _Maxcode_, _Mode_);
3924 frm_nxt = frm + (_frm_nxt - _frm);
3925 to_nxt = to + (_to_nxt - _to);
3926 return r;
3927}
3928
3929__codecvt_utf8_utf16<char32_t>::result
3930__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3931 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3932 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3933{
3934 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3935 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3936 const uint8_t* _frm_nxt = _frm;
3937 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3938 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3939 uint32_t* _to_nxt = _to;
3940 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3941 _Maxcode_, _Mode_);
3942 frm_nxt = frm + (_frm_nxt - _frm);
3943 to_nxt = to + (_to_nxt - _to);
3944 return r;
3945}
3946
3947__codecvt_utf8_utf16<char32_t>::result
3948__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3949 extern_type* to, extern_type*, extern_type*& to_nxt) const
3950{
3951 to_nxt = to;
3952 return noconv;
3953}
3954
3955int
Howard Hinnantc9834542011-05-31 15:34:58 +00003956__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003957{
3958 return 0;
3959}
3960
3961bool
Howard Hinnantc9834542011-05-31 15:34:58 +00003962__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003963{
3964 return false;
3965}
3966
3967int
3968__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3969 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3970{
3971 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3972 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3973 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3974}
3975
3976int
Howard Hinnantc9834542011-05-31 15:34:58 +00003977__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
Howard Hinnant87d1a8a2010-05-30 21:39:41 +00003978{
3979 if (_Mode_ & consume_header)
3980 return 7;
3981 return 4;
3982}
3983
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003984// __narrow_to_utf8<16>
3985
3986__narrow_to_utf8<16>::~__narrow_to_utf8()
3987{
3988}
3989
3990// __narrow_to_utf8<32>
3991
3992__narrow_to_utf8<32>::~__narrow_to_utf8()
3993{
3994}
3995
3996// __widen_from_utf8<16>
3997
3998__widen_from_utf8<16>::~__widen_from_utf8()
3999{
4000}
4001
4002// __widen_from_utf8<32>
4003
4004__widen_from_utf8<32>::~__widen_from_utf8()
4005{
4006}
4007
4008// numpunct<char> && numpunct<wchar_t>
4009
4010locale::id numpunct< char >::id;
4011locale::id numpunct<wchar_t>::id;
4012
4013numpunct<char>::numpunct(size_t refs)
4014 : locale::facet(refs),
4015 __decimal_point_('.'),
4016 __thousands_sep_(',')
4017{
4018}
4019
4020numpunct<wchar_t>::numpunct(size_t refs)
4021 : locale::facet(refs),
4022 __decimal_point_(L'.'),
4023 __thousands_sep_(L',')
4024{
4025}
4026
4027numpunct<char>::~numpunct()
4028{
4029}
4030
4031numpunct<wchar_t>::~numpunct()
4032{
4033}
4034
4035 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4036wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4037
4038 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4039wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4040
4041string numpunct< char >::do_grouping() const {return __grouping_;}
4042string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4043
4044 string numpunct< char >::do_truename() const {return "true";}
4045wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4046
4047 string numpunct< char >::do_falsename() const {return "false";}
4048wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4049
4050// numpunct_byname<char>
4051
4052numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4053 : numpunct<char>(refs)
4054{
4055 __init(nm);
4056}
4057
4058numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4059 : numpunct<char>(refs)
4060{
4061 __init(nm.c_str());
4062}
4063
4064numpunct_byname<char>::~numpunct_byname()
4065{
4066}
4067
4068void
4069numpunct_byname<char>::__init(const char* nm)
4070{
4071 if (strcmp(nm, "C") != 0)
4072 {
Sean Huntf3907e62011-07-15 05:40:33 +00004073 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004074#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004075 if (loc == 0)
4076 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4077 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004078#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00004079#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004080 lconv* lc = localeconv_l(loc.get());
4081#else
4082 lconv* lc = __localeconv_l(loc.get());
4083#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004084 if (*lc->decimal_point)
4085 __decimal_point_ = *lc->decimal_point;
4086 if (*lc->thousands_sep)
4087 __thousands_sep_ = *lc->thousands_sep;
4088 __grouping_ = lc->grouping;
Sean Huntcb05a082011-07-07 22:45:07 +00004089 // localization for truename and falsename is not available
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004090 }
4091}
4092
4093// numpunct_byname<wchar_t>
4094
4095numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4096 : numpunct<wchar_t>(refs)
4097{
4098 __init(nm);
4099}
4100
4101numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4102 : numpunct<wchar_t>(refs)
4103{
4104 __init(nm.c_str());
4105}
4106
4107numpunct_byname<wchar_t>::~numpunct_byname()
4108{
4109}
4110
4111void
4112numpunct_byname<wchar_t>::__init(const char* nm)
4113{
4114 if (strcmp(nm, "C") != 0)
4115 {
Sean Huntf3907e62011-07-15 05:40:33 +00004116 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00004117#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004118 if (loc == 0)
4119 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4120 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004121#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00004122#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004123 lconv* lc = localeconv_l(loc.get());
4124#else
4125 lconv* lc = __localeconv_l(loc.get());
4126#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004127 if (*lc->decimal_point)
4128 __decimal_point_ = *lc->decimal_point;
4129 if (*lc->thousands_sep)
4130 __thousands_sep_ = *lc->thousands_sep;
4131 __grouping_ = lc->grouping;
4132 // locallization for truename and falsename is not available
4133 }
4134}
4135
4136// num_get helpers
4137
4138int
4139__num_get_base::__get_base(ios_base& iob)
4140{
4141 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4142 if (__basefield == ios_base::oct)
4143 return 8;
4144 else if (__basefield == ios_base::hex)
4145 return 16;
4146 else if (__basefield == 0)
4147 return 0;
4148 return 10;
4149}
4150
4151const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4152
4153void
4154__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4155 ios_base::iostate& __err)
4156{
4157 if (__grouping.size() != 0)
4158 {
4159 reverse(__g, __g_end);
4160 const char* __ig = __grouping.data();
4161 const char* __eg = __ig + __grouping.size();
4162 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4163 {
4164 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4165 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00004166 if (static_cast<unsigned>(*__ig) != *__r)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004167 {
4168 __err = ios_base::failbit;
4169 return;
4170 }
4171 }
4172 if (__eg - __ig > 1)
4173 ++__ig;
4174 }
4175 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4176 {
Howard Hinnantec3773c2011-12-01 20:21:04 +00004177 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004178 __err = ios_base::failbit;
4179 }
4180 }
4181}
4182
4183void
4184__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4185 ios_base::fmtflags __flags)
4186{
4187 if (__flags & ios_base::showpos)
4188 *__fmtp++ = '+';
4189 if (__flags & ios_base::showbase)
4190 *__fmtp++ = '#';
4191 while(*__len)
4192 *__fmtp++ = *__len++;
4193 if ((__flags & ios_base::basefield) == ios_base::oct)
4194 *__fmtp = 'o';
4195 else if ((__flags & ios_base::basefield) == ios_base::hex)
4196 {
4197 if (__flags & ios_base::uppercase)
4198 *__fmtp = 'X';
4199 else
4200 *__fmtp = 'x';
4201 }
4202 else if (__signd)
4203 *__fmtp = 'd';
4204 else
4205 *__fmtp = 'u';
4206}
4207
4208bool
4209__num_put_base::__format_float(char* __fmtp, const char* __len,
4210 ios_base::fmtflags __flags)
4211{
4212 bool specify_precision = true;
4213 if (__flags & ios_base::showpos)
4214 *__fmtp++ = '+';
4215 if (__flags & ios_base::showpoint)
4216 *__fmtp++ = '#';
4217 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4218 bool uppercase = __flags & ios_base::uppercase;
4219 if (floatfield == (ios_base::fixed | ios_base::scientific))
4220 specify_precision = false;
4221 else
4222 {
4223 *__fmtp++ = '.';
4224 *__fmtp++ = '*';
4225 }
4226 while(*__len)
4227 *__fmtp++ = *__len++;
4228 if (floatfield == ios_base::fixed)
4229 {
4230 if (uppercase)
4231 *__fmtp = 'F';
4232 else
4233 *__fmtp = 'f';
4234 }
4235 else if (floatfield == ios_base::scientific)
4236 {
4237 if (uppercase)
4238 *__fmtp = 'E';
4239 else
4240 *__fmtp = 'e';
4241 }
4242 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4243 {
4244 if (uppercase)
4245 *__fmtp = 'A';
4246 else
4247 *__fmtp = 'a';
4248 }
4249 else
4250 {
4251 if (uppercase)
4252 *__fmtp = 'G';
4253 else
4254 *__fmtp = 'g';
4255 }
4256 return specify_precision;
4257}
4258
4259char*
4260__num_put_base::__identify_padding(char* __nb, char* __ne,
4261 const ios_base& __iob)
4262{
4263 switch (__iob.flags() & ios_base::adjustfield)
4264 {
4265 case ios_base::internal:
4266 if (__nb[0] == '-' || __nb[0] == '+')
4267 return __nb+1;
4268 if (__ne - __nb >= 2 && __nb[0] == '0'
4269 && (__nb[1] == 'x' || __nb[1] == 'X'))
4270 return __nb+2;
4271 break;
4272 case ios_base::left:
4273 return __ne;
4274 case ios_base::right:
4275 default:
4276 break;
4277 }
4278 return __nb;
4279}
4280
4281// time_get
4282
4283static
4284string*
4285init_weeks()
4286{
4287 static string weeks[14];
4288 weeks[0] = "Sunday";
4289 weeks[1] = "Monday";
4290 weeks[2] = "Tuesday";
4291 weeks[3] = "Wednesday";
4292 weeks[4] = "Thursday";
4293 weeks[5] = "Friday";
4294 weeks[6] = "Saturday";
4295 weeks[7] = "Sun";
4296 weeks[8] = "Mon";
4297 weeks[9] = "Tue";
4298 weeks[10] = "Wed";
4299 weeks[11] = "Thu";
4300 weeks[12] = "Fri";
4301 weeks[13] = "Sat";
4302 return weeks;
4303}
4304
4305static
4306wstring*
4307init_wweeks()
4308{
4309 static wstring weeks[14];
4310 weeks[0] = L"Sunday";
4311 weeks[1] = L"Monday";
4312 weeks[2] = L"Tuesday";
4313 weeks[3] = L"Wednesday";
4314 weeks[4] = L"Thursday";
4315 weeks[5] = L"Friday";
4316 weeks[6] = L"Saturday";
4317 weeks[7] = L"Sun";
4318 weeks[8] = L"Mon";
4319 weeks[9] = L"Tue";
4320 weeks[10] = L"Wed";
4321 weeks[11] = L"Thu";
4322 weeks[12] = L"Fri";
4323 weeks[13] = L"Sat";
4324 return weeks;
4325}
4326
4327template <>
4328const string*
4329__time_get_c_storage<char>::__weeks() const
4330{
4331 static const string* weeks = init_weeks();
4332 return weeks;
4333}
4334
4335template <>
4336const wstring*
4337__time_get_c_storage<wchar_t>::__weeks() const
4338{
4339 static const wstring* weeks = init_wweeks();
4340 return weeks;
4341}
4342
4343static
4344string*
4345init_months()
4346{
4347 static string months[24];
4348 months[0] = "January";
4349 months[1] = "February";
4350 months[2] = "March";
4351 months[3] = "April";
4352 months[4] = "May";
4353 months[5] = "June";
4354 months[6] = "July";
4355 months[7] = "August";
4356 months[8] = "September";
4357 months[9] = "October";
4358 months[10] = "November";
4359 months[11] = "December";
4360 months[12] = "Jan";
4361 months[13] = "Feb";
4362 months[14] = "Mar";
4363 months[15] = "Apr";
4364 months[16] = "May";
4365 months[17] = "Jun";
4366 months[18] = "Jul";
4367 months[19] = "Aug";
4368 months[20] = "Sep";
4369 months[21] = "Oct";
4370 months[22] = "Nov";
4371 months[23] = "Dec";
4372 return months;
4373}
4374
4375static
4376wstring*
4377init_wmonths()
4378{
4379 static wstring months[24];
4380 months[0] = L"January";
4381 months[1] = L"February";
4382 months[2] = L"March";
4383 months[3] = L"April";
4384 months[4] = L"May";
4385 months[5] = L"June";
4386 months[6] = L"July";
4387 months[7] = L"August";
4388 months[8] = L"September";
4389 months[9] = L"October";
4390 months[10] = L"November";
4391 months[11] = L"December";
4392 months[12] = L"Jan";
4393 months[13] = L"Feb";
4394 months[14] = L"Mar";
4395 months[15] = L"Apr";
4396 months[16] = L"May";
4397 months[17] = L"Jun";
4398 months[18] = L"Jul";
4399 months[19] = L"Aug";
4400 months[20] = L"Sep";
4401 months[21] = L"Oct";
4402 months[22] = L"Nov";
4403 months[23] = L"Dec";
4404 return months;
4405}
4406
4407template <>
4408const string*
4409__time_get_c_storage<char>::__months() const
4410{
4411 static const string* months = init_months();
4412 return months;
4413}
4414
4415template <>
4416const wstring*
4417__time_get_c_storage<wchar_t>::__months() const
4418{
4419 static const wstring* months = init_wmonths();
4420 return months;
4421}
4422
4423static
4424string*
4425init_am_pm()
4426{
4427 static string am_pm[24];
4428 am_pm[0] = "AM";
4429 am_pm[1] = "PM";
4430 return am_pm;
4431}
4432
4433static
4434wstring*
4435init_wam_pm()
4436{
4437 static wstring am_pm[24];
4438 am_pm[0] = L"AM";
4439 am_pm[1] = L"PM";
4440 return am_pm;
4441}
4442
4443template <>
4444const string*
4445__time_get_c_storage<char>::__am_pm() const
4446{
4447 static const string* am_pm = init_am_pm();
4448 return am_pm;
4449}
4450
4451template <>
4452const wstring*
4453__time_get_c_storage<wchar_t>::__am_pm() const
4454{
4455 static const wstring* am_pm = init_wam_pm();
4456 return am_pm;
4457}
4458
4459template <>
4460const string&
4461__time_get_c_storage<char>::__x() const
4462{
4463 static string s("%m/%d/%y");
4464 return s;
4465}
4466
4467template <>
4468const wstring&
4469__time_get_c_storage<wchar_t>::__x() const
4470{
4471 static wstring s(L"%m/%d/%y");
4472 return s;
4473}
4474
4475template <>
4476const string&
4477__time_get_c_storage<char>::__X() const
4478{
4479 static string s("%H:%M:%S");
4480 return s;
4481}
4482
4483template <>
4484const wstring&
4485__time_get_c_storage<wchar_t>::__X() const
4486{
4487 static wstring s(L"%H:%M:%S");
4488 return s;
4489}
4490
4491template <>
4492const string&
4493__time_get_c_storage<char>::__c() const
4494{
4495 static string s("%a %b %d %H:%M:%S %Y");
4496 return s;
4497}
4498
4499template <>
4500const wstring&
4501__time_get_c_storage<wchar_t>::__c() const
4502{
4503 static wstring s(L"%a %b %d %H:%M:%S %Y");
4504 return s;
4505}
4506
4507template <>
4508const string&
4509__time_get_c_storage<char>::__r() const
4510{
4511 static string s("%I:%M:%S %p");
4512 return s;
4513}
4514
4515template <>
4516const wstring&
4517__time_get_c_storage<wchar_t>::__r() const
4518{
4519 static wstring s(L"%I:%M:%S %p");
4520 return s;
4521}
4522
4523// time_get_byname
4524
4525__time_get::__time_get(const char* nm)
4526 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4527{
Howard Hinnantd4444702010-08-11 17:04:31 +00004528#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004529 if (__loc_ == 0)
4530 throw runtime_error("time_get_byname"
4531 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004532#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004533}
4534
4535__time_get::__time_get(const string& nm)
4536 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4537{
Howard Hinnantd4444702010-08-11 17:04:31 +00004538#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004539 if (__loc_ == 0)
4540 throw runtime_error("time_get_byname"
4541 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00004542#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004543}
4544
4545__time_get::~__time_get()
4546{
4547 freelocale(__loc_);
4548}
4549
4550template <>
4551string
4552__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4553{
Howard Hinnant3074a052012-02-19 14:55:32 +00004554 tm t = {0};
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004555 t.tm_sec = 59;
4556 t.tm_min = 55;
4557 t.tm_hour = 23;
4558 t.tm_mday = 31;
4559 t.tm_mon = 11;
4560 t.tm_year = 161;
4561 t.tm_wday = 6;
4562 t.tm_yday = 364;
4563 t.tm_isdst = -1;
4564 char buf[100];
4565 char f[3] = {0};
4566 f[0] = '%';
4567 f[1] = fmt;
4568 size_t n = strftime_l(buf, 100, f, &t, __loc_);
4569 char* bb = buf;
4570 char* be = buf + n;
4571 string result;
4572 while (bb != be)
4573 {
4574 if (ct.is(ctype_base::space, *bb))
4575 {
4576 result.push_back(' ');
4577 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4578 ;
4579 continue;
4580 }
4581 char* w = bb;
4582 ios_base::iostate err = ios_base::goodbit;
Howard Hinnantec3773c2011-12-01 20:21:04 +00004583 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004584 ct, err, false)
4585 - this->__weeks_;
4586 if (i < 14)
4587 {
4588 result.push_back('%');
4589 if (i < 7)
4590 result.push_back('A');
4591 else
4592 result.push_back('a');
4593 bb = w;
4594 continue;
4595 }
4596 w = bb;
4597 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4598 ct, err, false)
4599 - this->__months_;
4600 if (i < 24)
4601 {
4602 result.push_back('%');
4603 if (i < 12)
4604 result.push_back('B');
4605 else
4606 result.push_back('b');
4607 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4608 result.back() = 'm';
4609 bb = w;
4610 continue;
4611 }
4612 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4613 {
4614 w = bb;
4615 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4616 ct, err, false) - this->__am_pm_;
4617 if (i < 2)
4618 {
4619 result.push_back('%');
4620 result.push_back('p');
4621 bb = w;
4622 continue;
4623 }
4624 }
4625 w = bb;
4626 if (ct.is(ctype_base::digit, *bb))
4627 {
4628 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4629 {
4630 case 6:
4631 result.push_back('%');
4632 result.push_back('w');
4633 break;
4634 case 7:
4635 result.push_back('%');
4636 result.push_back('u');
4637 break;
4638 case 11:
4639 result.push_back('%');
4640 result.push_back('I');
4641 break;
4642 case 12:
4643 result.push_back('%');
4644 result.push_back('m');
4645 break;
4646 case 23:
4647 result.push_back('%');
4648 result.push_back('H');
4649 break;
4650 case 31:
4651 result.push_back('%');
4652 result.push_back('d');
4653 break;
4654 case 55:
4655 result.push_back('%');
4656 result.push_back('M');
4657 break;
4658 case 59:
4659 result.push_back('%');
4660 result.push_back('S');
4661 break;
4662 case 61:
4663 result.push_back('%');
4664 result.push_back('y');
4665 break;
4666 case 364:
4667 result.push_back('%');
4668 result.push_back('j');
4669 break;
4670 case 2061:
4671 result.push_back('%');
4672 result.push_back('Y');
4673 break;
4674 default:
4675 for (; w != bb; ++w)
4676 result.push_back(*w);
4677 break;
4678 }
4679 continue;
4680 }
4681 if (*bb == '%')
4682 {
4683 result.push_back('%');
4684 result.push_back('%');
4685 ++bb;
4686 continue;
4687 }
4688 result.push_back(*bb);
4689 ++bb;
4690 }
4691 return result;
4692}
4693
Howard Hinnantec3773c2011-12-01 20:21:04 +00004694#pragma clang diagnostic ignored "-Wmissing-braces"
4695#pragma clang diagnostic ignored "-Wmissing-field-initializers"
4696
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004697template <>
4698wstring
4699__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4700{
Howard Hinnant3074a052012-02-19 14:55:32 +00004701 tm t = {0};
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004702 t.tm_sec = 59;
4703 t.tm_min = 55;
4704 t.tm_hour = 23;
4705 t.tm_mday = 31;
4706 t.tm_mon = 11;
4707 t.tm_year = 161;
4708 t.tm_wday = 6;
4709 t.tm_yday = 364;
4710 t.tm_isdst = -1;
4711 char buf[100];
4712 char f[3] = {0};
4713 f[0] = '%';
4714 f[1] = fmt;
Howard Hinnantec3773c2011-12-01 20:21:04 +00004715 strftime_l(buf, 100, f, &t, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004716 wchar_t wbuf[100];
4717 wchar_t* wbb = wbuf;
4718 mbstate_t mb = {0};
4719 const char* bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004720#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantec3773c2011-12-01 20:21:04 +00004721 size_t j = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Sean Huntf3907e62011-07-15 05:40:33 +00004722#else
Howard Hinnantec3773c2011-12-01 20:21:04 +00004723 size_t j = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
Sean Huntf3907e62011-07-15 05:40:33 +00004724#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004725 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004726 __throw_runtime_error("locale not supported");
Howard Hinnantec3773c2011-12-01 20:21:04 +00004727 wchar_t* wbe = wbb + j;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004728 wstring result;
4729 while (wbb != wbe)
4730 {
4731 if (ct.is(ctype_base::space, *wbb))
4732 {
4733 result.push_back(L' ');
4734 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4735 ;
4736 continue;
4737 }
4738 wchar_t* w = wbb;
4739 ios_base::iostate err = ios_base::goodbit;
Howard Hinnantec3773c2011-12-01 20:21:04 +00004740 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004741 ct, err, false)
4742 - this->__weeks_;
4743 if (i < 14)
4744 {
4745 result.push_back(L'%');
4746 if (i < 7)
4747 result.push_back(L'A');
4748 else
4749 result.push_back(L'a');
4750 wbb = w;
4751 continue;
4752 }
4753 w = wbb;
4754 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4755 ct, err, false)
4756 - this->__months_;
4757 if (i < 24)
4758 {
4759 result.push_back(L'%');
4760 if (i < 12)
4761 result.push_back(L'B');
4762 else
4763 result.push_back(L'b');
4764 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4765 result.back() = L'm';
4766 wbb = w;
4767 continue;
4768 }
4769 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4770 {
4771 w = wbb;
4772 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4773 ct, err, false) - this->__am_pm_;
4774 if (i < 2)
4775 {
4776 result.push_back(L'%');
4777 result.push_back(L'p');
4778 wbb = w;
4779 continue;
4780 }
4781 }
4782 w = wbb;
4783 if (ct.is(ctype_base::digit, *wbb))
4784 {
4785 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4786 {
4787 case 6:
4788 result.push_back(L'%');
4789 result.push_back(L'w');
4790 break;
4791 case 7:
4792 result.push_back(L'%');
4793 result.push_back(L'u');
4794 break;
4795 case 11:
4796 result.push_back(L'%');
4797 result.push_back(L'I');
4798 break;
4799 case 12:
4800 result.push_back(L'%');
4801 result.push_back(L'm');
4802 break;
4803 case 23:
4804 result.push_back(L'%');
4805 result.push_back(L'H');
4806 break;
4807 case 31:
4808 result.push_back(L'%');
4809 result.push_back(L'd');
4810 break;
4811 case 55:
4812 result.push_back(L'%');
4813 result.push_back(L'M');
4814 break;
4815 case 59:
4816 result.push_back(L'%');
4817 result.push_back(L'S');
4818 break;
4819 case 61:
4820 result.push_back(L'%');
4821 result.push_back(L'y');
4822 break;
4823 case 364:
4824 result.push_back(L'%');
4825 result.push_back(L'j');
4826 break;
4827 case 2061:
4828 result.push_back(L'%');
4829 result.push_back(L'Y');
4830 break;
4831 default:
4832 for (; w != wbb; ++w)
4833 result.push_back(*w);
4834 break;
4835 }
4836 continue;
4837 }
4838 if (ct.narrow(*wbb, 0) == '%')
4839 {
4840 result.push_back(L'%');
4841 result.push_back(L'%');
4842 ++wbb;
4843 continue;
4844 }
4845 result.push_back(*wbb);
4846 ++wbb;
4847 }
4848 return result;
4849}
4850
4851template <>
4852void
4853__time_get_storage<char>::init(const ctype<char>& ct)
4854{
4855 tm t;
4856 char buf[100];
4857 // __weeks_
4858 for (int i = 0; i < 7; ++i)
4859 {
4860 t.tm_wday = i;
4861 strftime_l(buf, 100, "%A", &t, __loc_);
4862 __weeks_[i] = buf;
4863 strftime_l(buf, 100, "%a", &t, __loc_);
4864 __weeks_[i+7] = buf;
4865 }
4866 // __months_
4867 for (int i = 0; i < 12; ++i)
4868 {
4869 t.tm_mon = i;
4870 strftime_l(buf, 100, "%B", &t, __loc_);
4871 __months_[i] = buf;
4872 strftime_l(buf, 100, "%b", &t, __loc_);
4873 __months_[i+12] = buf;
4874 }
4875 // __am_pm_
4876 t.tm_hour = 1;
4877 strftime_l(buf, 100, "%p", &t, __loc_);
4878 __am_pm_[0] = buf;
4879 t.tm_hour = 13;
4880 strftime_l(buf, 100, "%p", &t, __loc_);
4881 __am_pm_[1] = buf;
4882 __c_ = __analyze('c', ct);
4883 __r_ = __analyze('r', ct);
4884 __x_ = __analyze('x', ct);
4885 __X_ = __analyze('X', ct);
4886}
4887
4888template <>
4889void
4890__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4891{
4892 tm t = {0};
4893 char buf[100];
4894 size_t be;
4895 wchar_t wbuf[100];
4896 wchar_t* wbe;
4897 mbstate_t mb = {0};
4898 // __weeks_
4899 for (int i = 0; i < 7; ++i)
4900 {
4901 t.tm_wday = i;
4902 be = strftime_l(buf, 100, "%A", &t, __loc_);
4903 mb = mbstate_t();
4904 const char* bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004905#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004906 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4907#else
4908 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4909#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004910 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004911 __throw_runtime_error("locale not supported");
4912 wbe = wbuf + j;
4913 __weeks_[i].assign(wbuf, wbe);
4914 be = strftime_l(buf, 100, "%a", &t, __loc_);
4915 mb = mbstate_t();
4916 bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004917#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004918 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4919#else
4920 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4921#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004922 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004923 __throw_runtime_error("locale not supported");
4924 wbe = wbuf + j;
4925 __weeks_[i+7].assign(wbuf, wbe);
4926 }
4927 // __months_
4928 for (int i = 0; i < 12; ++i)
4929 {
4930 t.tm_mon = i;
4931 be = strftime_l(buf, 100, "%B", &t, __loc_);
4932 mb = mbstate_t();
4933 const char* bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004934#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004935 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4936#else
4937 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4938#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004939 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004940 __throw_runtime_error("locale not supported");
4941 wbe = wbuf + j;
4942 __months_[i].assign(wbuf, wbe);
4943 be = strftime_l(buf, 100, "%b", &t, __loc_);
4944 mb = mbstate_t();
4945 bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004946#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004947 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4948#else
4949 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4950#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004951 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004952 __throw_runtime_error("locale not supported");
4953 wbe = wbuf + j;
4954 __months_[i+12].assign(wbuf, wbe);
4955 }
4956 // __am_pm_
4957 t.tm_hour = 1;
4958 be = strftime_l(buf, 100, "%p", &t, __loc_);
4959 mb = mbstate_t();
4960 const char* bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004961#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004962 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4963#else
4964 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4965#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004966 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004967 __throw_runtime_error("locale not supported");
4968 wbe = wbuf + j;
4969 __am_pm_[0].assign(wbuf, wbe);
4970 t.tm_hour = 13;
4971 be = strftime_l(buf, 100, "%p", &t, __loc_);
4972 mb = mbstate_t();
4973 bb = buf;
Howard Hinnant866569b2011-09-28 23:39:33 +00004974#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00004975 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4976#else
4977 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4978#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00004979 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00004980 __throw_runtime_error("locale not supported");
4981 wbe = wbuf + j;
4982 __am_pm_[1].assign(wbuf, wbe);
4983 __c_ = __analyze('c', ct);
4984 __r_ = __analyze('r', ct);
4985 __x_ = __analyze('x', ct);
4986 __X_ = __analyze('X', ct);
4987}
4988
4989template <class CharT>
4990struct _LIBCPP_HIDDEN __time_get_temp
4991 : public ctype_byname<CharT>
4992{
4993 explicit __time_get_temp(const char* nm)
4994 : ctype_byname<CharT>(nm, 1) {}
4995 explicit __time_get_temp(const string& nm)
4996 : ctype_byname<CharT>(nm, 1) {}
4997};
4998
4999template <>
5000__time_get_storage<char>::__time_get_storage(const char* __nm)
5001 : __time_get(__nm)
5002{
5003 const __time_get_temp<char> ct(__nm);
5004 init(ct);
5005}
5006
5007template <>
5008__time_get_storage<char>::__time_get_storage(const string& __nm)
5009 : __time_get(__nm)
5010{
5011 const __time_get_temp<char> ct(__nm);
5012 init(ct);
5013}
5014
5015template <>
5016__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5017 : __time_get(__nm)
5018{
5019 const __time_get_temp<wchar_t> ct(__nm);
5020 init(ct);
5021}
5022
5023template <>
5024__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5025 : __time_get(__nm)
5026{
5027 const __time_get_temp<wchar_t> ct(__nm);
5028 init(ct);
5029}
5030
5031template <>
5032time_base::dateorder
5033__time_get_storage<char>::__do_date_order() const
5034{
5035 unsigned i;
5036 for (i = 0; i < __x_.size(); ++i)
5037 if (__x_[i] == '%')
5038 break;
5039 ++i;
5040 switch (__x_[i])
5041 {
5042 case 'y':
5043 case 'Y':
5044 for (++i; i < __x_.size(); ++i)
5045 if (__x_[i] == '%')
5046 break;
5047 if (i == __x_.size())
5048 break;
5049 ++i;
5050 switch (__x_[i])
5051 {
5052 case 'm':
5053 for (++i; i < __x_.size(); ++i)
5054 if (__x_[i] == '%')
5055 break;
5056 if (i == __x_.size())
5057 break;
5058 ++i;
5059 if (__x_[i] == 'd')
5060 return time_base::ymd;
5061 break;
5062 case 'd':
5063 for (++i; i < __x_.size(); ++i)
5064 if (__x_[i] == '%')
5065 break;
5066 if (i == __x_.size())
5067 break;
5068 ++i;
5069 if (__x_[i] == 'm')
5070 return time_base::ydm;
5071 break;
5072 }
5073 break;
5074 case 'm':
5075 for (++i; i < __x_.size(); ++i)
5076 if (__x_[i] == '%')
5077 break;
5078 if (i == __x_.size())
5079 break;
5080 ++i;
5081 if (__x_[i] == 'd')
5082 {
5083 for (++i; i < __x_.size(); ++i)
5084 if (__x_[i] == '%')
5085 break;
5086 if (i == __x_.size())
5087 break;
5088 ++i;
5089 if (__x_[i] == 'y' || __x_[i] == 'Y')
5090 return time_base::mdy;
5091 break;
5092 }
5093 break;
5094 case 'd':
5095 for (++i; i < __x_.size(); ++i)
5096 if (__x_[i] == '%')
5097 break;
5098 if (i == __x_.size())
5099 break;
5100 ++i;
5101 if (__x_[i] == 'm')
5102 {
5103 for (++i; i < __x_.size(); ++i)
5104 if (__x_[i] == '%')
5105 break;
5106 if (i == __x_.size())
5107 break;
5108 ++i;
5109 if (__x_[i] == 'y' || __x_[i] == 'Y')
5110 return time_base::dmy;
5111 break;
5112 }
5113 break;
5114 }
5115 return time_base::no_order;
5116}
5117
5118template <>
5119time_base::dateorder
5120__time_get_storage<wchar_t>::__do_date_order() const
5121{
5122 unsigned i;
5123 for (i = 0; i < __x_.size(); ++i)
5124 if (__x_[i] == L'%')
5125 break;
5126 ++i;
5127 switch (__x_[i])
5128 {
5129 case L'y':
5130 case L'Y':
5131 for (++i; i < __x_.size(); ++i)
5132 if (__x_[i] == L'%')
5133 break;
5134 if (i == __x_.size())
5135 break;
5136 ++i;
5137 switch (__x_[i])
5138 {
5139 case L'm':
5140 for (++i; i < __x_.size(); ++i)
5141 if (__x_[i] == L'%')
5142 break;
5143 if (i == __x_.size())
5144 break;
5145 ++i;
5146 if (__x_[i] == L'd')
5147 return time_base::ymd;
5148 break;
5149 case L'd':
5150 for (++i; i < __x_.size(); ++i)
5151 if (__x_[i] == L'%')
5152 break;
5153 if (i == __x_.size())
5154 break;
5155 ++i;
5156 if (__x_[i] == L'm')
5157 return time_base::ydm;
5158 break;
5159 }
5160 break;
5161 case L'm':
5162 for (++i; i < __x_.size(); ++i)
5163 if (__x_[i] == L'%')
5164 break;
5165 if (i == __x_.size())
5166 break;
5167 ++i;
5168 if (__x_[i] == L'd')
5169 {
5170 for (++i; i < __x_.size(); ++i)
5171 if (__x_[i] == L'%')
5172 break;
5173 if (i == __x_.size())
5174 break;
5175 ++i;
5176 if (__x_[i] == L'y' || __x_[i] == L'Y')
5177 return time_base::mdy;
5178 break;
5179 }
5180 break;
5181 case L'd':
5182 for (++i; i < __x_.size(); ++i)
5183 if (__x_[i] == L'%')
5184 break;
5185 if (i == __x_.size())
5186 break;
5187 ++i;
5188 if (__x_[i] == L'm')
5189 {
5190 for (++i; i < __x_.size(); ++i)
5191 if (__x_[i] == L'%')
5192 break;
5193 if (i == __x_.size())
5194 break;
5195 ++i;
5196 if (__x_[i] == L'y' || __x_[i] == L'Y')
5197 return time_base::dmy;
5198 break;
5199 }
5200 break;
5201 }
5202 return time_base::no_order;
5203}
5204
5205// time_put
5206
5207__time_put::__time_put(const char* nm)
5208 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5209{
Howard Hinnantd4444702010-08-11 17:04:31 +00005210#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005211 if (__loc_ == 0)
5212 throw runtime_error("time_put_byname"
5213 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005214#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005215}
5216
5217__time_put::__time_put(const string& nm)
5218 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5219{
Howard Hinnantd4444702010-08-11 17:04:31 +00005220#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005221 if (__loc_ == 0)
5222 throw runtime_error("time_put_byname"
5223 " failed to construct for " + nm);
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005224#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005225}
5226
5227__time_put::~__time_put()
5228{
5229 if (__loc_)
5230 freelocale(__loc_);
5231}
5232
5233void
5234__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5235 char __fmt, char __mod) const
5236{
5237 char fmt[] = {'%', __fmt, __mod, 0};
5238 if (__mod != 0)
5239 swap(fmt[1], fmt[2]);
Howard Hinnantec3773c2011-12-01 20:21:04 +00005240 size_t n = strftime_l(__nb, static_cast<size_t>(__ne-__nb), fmt, __tm, __loc_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005241 __ne = __nb + n;
5242}
5243
5244void
5245__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5246 char __fmt, char __mod) const
5247{
5248 char __nar[100];
5249 char* __ne = __nar + 100;
5250 __do_put(__nar, __ne, __tm, __fmt, __mod);
5251 mbstate_t mb = {0};
5252 const char* __nb = __nar;
Howard Hinnant866569b2011-09-28 23:39:33 +00005253#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005254 size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5255#else
5256 size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5257#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005258 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005259 __throw_runtime_error("locale not supported");
5260 __we = __wb + j;
5261}
5262
5263// moneypunct_byname
5264
5265static
5266void
5267__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5268{
5269 const char sign = static_cast<char>(money_base::sign);
5270 const char space = static_cast<char>(money_base::space);
5271 const char none = static_cast<char>(money_base::none);
5272 const char symbol = static_cast<char>(money_base::symbol);
5273 const char value = static_cast<char>(money_base::value);
5274 switch (cs_precedes)
5275 {
5276 case 0:
5277 switch (sign_posn)
5278 {
5279 case 0:
5280 pat.field[0] = sign;
5281 pat.field[1] = value;
5282 pat.field[3] = symbol;
5283 switch (sep_by_space)
5284 {
5285 case 0:
5286 pat.field[2] = none;
5287 return;
5288 case 1:
5289 case 2:
5290 pat.field[2] = space;
5291 return;
5292 default:
5293 break;
5294 }
5295 break;
5296 case 1:
5297 pat.field[0] = sign;
5298 pat.field[3] = symbol;
5299 switch (sep_by_space)
5300 {
5301 case 0:
5302 pat.field[1] = value;
5303 pat.field[2] = none;
5304 return;
5305 case 1:
5306 pat.field[1] = value;
5307 pat.field[2] = space;
5308 return;
5309 case 2:
5310 pat.field[1] = space;
5311 pat.field[2] = value;
5312 return;
5313 default:
5314 break;
5315 }
5316 break;
5317 case 2:
5318 pat.field[0] = value;
5319 pat.field[3] = sign;
5320 switch (sep_by_space)
5321 {
5322 case 0:
5323 pat.field[1] = none;
5324 pat.field[2] = symbol;
5325 return;
5326 case 1:
5327 pat.field[1] = space;
5328 pat.field[2] = symbol;
5329 return;
5330 case 2:
5331 pat.field[1] = symbol;
5332 pat.field[2] = space;
5333 return;
5334 default:
5335 break;
5336 }
5337 break;
5338 case 3:
5339 pat.field[0] = value;
5340 pat.field[3] = symbol;
5341 switch (sep_by_space)
5342 {
5343 case 0:
5344 pat.field[1] = none;
5345 pat.field[2] = sign;
5346 return;
5347 case 1:
5348 pat.field[1] = space;
5349 pat.field[2] = sign;
5350 return;
5351 case 2:
5352 pat.field[1] = sign;
5353 pat.field[2] = space;
5354 return;
5355 default:
5356 break;
5357 }
5358 break;
5359 case 4:
5360 pat.field[0] = value;
5361 pat.field[3] = sign;
5362 switch (sep_by_space)
5363 {
5364 case 0:
5365 pat.field[1] = none;
5366 pat.field[2] = symbol;
5367 return;
5368 case 1:
5369 pat.field[1] = space;
5370 pat.field[2] = symbol;
5371 return;
5372 case 2:
5373 pat.field[1] = symbol;
5374 pat.field[2] = space;
5375 return;
5376 default:
5377 break;
5378 }
5379 break;
5380 default:
5381 break;
5382 }
5383 break;
5384 case 1:
5385 switch (sign_posn)
5386 {
5387 case 0:
5388 pat.field[0] = sign;
5389 pat.field[1] = symbol;
5390 pat.field[3] = value;
5391 switch (sep_by_space)
5392 {
5393 case 0:
5394 pat.field[2] = none;
5395 return;
5396 case 1:
5397 case 2:
5398 pat.field[2] = space;
5399 return;
5400 default:
5401 break;
5402 }
5403 break;
5404 case 1:
5405 pat.field[0] = sign;
5406 pat.field[3] = value;
5407 switch (sep_by_space)
5408 {
5409 case 0:
5410 pat.field[1] = symbol;
5411 pat.field[2] = none;
5412 return;
5413 case 1:
5414 pat.field[1] = symbol;
5415 pat.field[2] = space;
5416 return;
5417 case 2:
5418 pat.field[1] = space;
5419 pat.field[2] = symbol;
5420 return;
5421 default:
5422 break;
5423 }
5424 break;
5425 case 2:
5426 pat.field[0] = symbol;
5427 pat.field[3] = sign;
5428 switch (sep_by_space)
5429 {
5430 case 0:
5431 pat.field[1] = none;
5432 pat.field[2] = value;
5433 return;
5434 case 1:
5435 pat.field[1] = space;
5436 pat.field[2] = value;
5437 return;
5438 case 2:
5439 pat.field[1] = value;
5440 pat.field[2] = space;
5441 return;
5442 default:
5443 break;
5444 }
5445 break;
5446 case 3:
5447 pat.field[0] = sign;
5448 pat.field[3] = value;
5449 switch (sep_by_space)
5450 {
5451 case 0:
5452 pat.field[1] = symbol;
5453 pat.field[2] = none;
5454 return;
5455 case 1:
5456 pat.field[1] = symbol;
5457 pat.field[2] = space;
5458 return;
5459 case 2:
5460 pat.field[1] = space;
5461 pat.field[2] = symbol;
5462 return;
5463 default:
5464 break;
5465 }
5466 break;
5467 case 4:
5468 pat.field[0] = symbol;
5469 pat.field[3] = value;
5470 switch (sep_by_space)
5471 {
5472 case 0:
5473 pat.field[1] = sign;
5474 pat.field[2] = none;
5475 return;
5476 case 1:
5477 pat.field[1] = sign;
5478 pat.field[2] = space;
5479 return;
5480 case 2:
5481 pat.field[1] = space;
5482 pat.field[2] = sign;
5483 return;
5484 default:
5485 break;
5486 }
5487 break;
5488 default:
5489 break;
5490 }
5491 break;
5492 default:
5493 break;
5494 }
5495 pat.field[0] = symbol;
5496 pat.field[1] = sign;
5497 pat.field[2] = none;
5498 pat.field[3] = value;
5499}
5500
5501template<>
5502void
5503moneypunct_byname<char, false>::init(const char* nm)
5504{
5505 typedef moneypunct<char, false> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005506 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005507#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005508 if (loc == 0)
5509 throw runtime_error("moneypunct_byname"
5510 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005511#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00005512#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005513 lconv* lc = localeconv_l(loc.get());
5514#else
5515 lconv* lc = __localeconv_l(loc.get());
5516#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005517 if (*lc->mon_decimal_point)
5518 __decimal_point_ = *lc->mon_decimal_point;
5519 else
5520 __decimal_point_ = base::do_decimal_point();
5521 if (*lc->mon_thousands_sep)
5522 __thousands_sep_ = *lc->mon_thousands_sep;
5523 else
5524 __thousands_sep_ = base::do_thousands_sep();
5525 __grouping_ = lc->mon_grouping;
5526 __curr_symbol_ = lc->currency_symbol;
5527 if (lc->frac_digits != CHAR_MAX)
5528 __frac_digits_ = lc->frac_digits;
5529 else
5530 __frac_digits_ = base::do_frac_digits();
5531 if (lc->p_sign_posn == 0)
5532 __positive_sign_ = "()";
5533 else
5534 __positive_sign_ = lc->positive_sign;
5535 if (lc->n_sign_posn == 0)
5536 __negative_sign_ = "()";
5537 else
5538 __negative_sign_ = lc->negative_sign;
5539 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5540 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5541}
5542
5543template<>
5544void
5545moneypunct_byname<char, true>::init(const char* nm)
5546{
5547 typedef moneypunct<char, true> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005548 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005549#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005550 if (loc == 0)
5551 throw runtime_error("moneypunct_byname"
5552 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005553#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00005554#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005555 lconv* lc = localeconv_l(loc.get());
5556#else
5557 lconv* lc = __localeconv_l(loc.get());
5558#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005559 if (*lc->mon_decimal_point)
5560 __decimal_point_ = *lc->mon_decimal_point;
5561 else
5562 __decimal_point_ = base::do_decimal_point();
5563 if (*lc->mon_thousands_sep)
5564 __thousands_sep_ = *lc->mon_thousands_sep;
5565 else
5566 __thousands_sep_ = base::do_thousands_sep();
5567 __grouping_ = lc->mon_grouping;
5568 __curr_symbol_ = lc->int_curr_symbol;
5569 if (lc->int_frac_digits != CHAR_MAX)
5570 __frac_digits_ = lc->int_frac_digits;
5571 else
5572 __frac_digits_ = base::do_frac_digits();
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005573#if _WIN32
5574 if (lc->p_sign_posn == 0)
5575#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005576 if (lc->int_p_sign_posn == 0)
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005577#endif //_WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005578 __positive_sign_ = "()";
5579 else
5580 __positive_sign_ = lc->positive_sign;
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005581#if _WIN32
5582 if(lc->n_sign_posn == 0)
5583#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005584 if (lc->int_n_sign_posn == 0)
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005585#endif // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005586 __negative_sign_ = "()";
5587 else
5588 __negative_sign_ = lc->negative_sign;
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005589#if _WIN32
5590 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5591 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5592#else
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005593 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5594 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005595#endif // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005596}
5597
5598template<>
5599void
5600moneypunct_byname<wchar_t, false>::init(const char* nm)
5601{
5602 typedef moneypunct<wchar_t, false> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005603 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005604#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005605 if (loc == 0)
5606 throw runtime_error("moneypunct_byname"
5607 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005608#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00005609#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005610 lconv* lc = localeconv_l(loc.get());
5611#else
5612 lconv* lc = __localeconv_l(loc.get());
5613#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005614 if (*lc->mon_decimal_point)
5615 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5616 else
5617 __decimal_point_ = base::do_decimal_point();
5618 if (*lc->mon_thousands_sep)
5619 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5620 else
5621 __thousands_sep_ = base::do_thousands_sep();
5622 __grouping_ = lc->mon_grouping;
5623 wchar_t wbuf[100];
5624 mbstate_t mb = {0};
5625 const char* bb = lc->currency_symbol;
Howard Hinnant866569b2011-09-28 23:39:33 +00005626#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005627 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5628#else
5629 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5630#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005631 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005632 __throw_runtime_error("locale not supported");
5633 wchar_t* wbe = wbuf + j;
5634 __curr_symbol_.assign(wbuf, wbe);
5635 if (lc->frac_digits != CHAR_MAX)
5636 __frac_digits_ = lc->frac_digits;
5637 else
5638 __frac_digits_ = base::do_frac_digits();
5639 if (lc->p_sign_posn == 0)
5640 __positive_sign_ = L"()";
5641 else
5642 {
5643 mb = mbstate_t();
5644 bb = lc->positive_sign;
Howard Hinnant866569b2011-09-28 23:39:33 +00005645#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005646 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5647#else
5648 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5649#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005650 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005651 __throw_runtime_error("locale not supported");
5652 wbe = wbuf + j;
5653 __positive_sign_.assign(wbuf, wbe);
5654 }
5655 if (lc->n_sign_posn == 0)
5656 __negative_sign_ = L"()";
5657 else
5658 {
5659 mb = mbstate_t();
5660 bb = lc->negative_sign;
Howard Hinnant866569b2011-09-28 23:39:33 +00005661#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005662 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5663#else
5664 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5665#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005666 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005667 __throw_runtime_error("locale not supported");
5668 wbe = wbuf + j;
5669 __negative_sign_.assign(wbuf, wbe);
5670 }
5671 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5672 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5673}
5674
5675template<>
5676void
5677moneypunct_byname<wchar_t, true>::init(const char* nm)
5678{
5679 typedef moneypunct<wchar_t, true> base;
Sean Huntf3907e62011-07-15 05:40:33 +00005680 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
Howard Hinnantd4444702010-08-11 17:04:31 +00005681#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005682 if (loc == 0)
5683 throw runtime_error("moneypunct_byname"
5684 " failed to construct for " + string(nm));
Howard Hinnant16e6e1d2010-08-22 00:03:27 +00005685#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant866569b2011-09-28 23:39:33 +00005686#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005687 lconv* lc = localeconv_l(loc.get());
5688#else
5689 lconv* lc = __localeconv_l(loc.get());
5690#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005691 if (*lc->mon_decimal_point)
5692 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5693 else
5694 __decimal_point_ = base::do_decimal_point();
5695 if (*lc->mon_thousands_sep)
5696 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5697 else
5698 __thousands_sep_ = base::do_thousands_sep();
5699 __grouping_ = lc->mon_grouping;
5700 wchar_t wbuf[100];
5701 mbstate_t mb = {0};
5702 const char* bb = lc->int_curr_symbol;
Howard Hinnant866569b2011-09-28 23:39:33 +00005703#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005704 size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5705#else
5706 size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5707#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005708 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005709 __throw_runtime_error("locale not supported");
5710 wchar_t* wbe = wbuf + j;
5711 __curr_symbol_.assign(wbuf, wbe);
5712 if (lc->int_frac_digits != CHAR_MAX)
5713 __frac_digits_ = lc->int_frac_digits;
5714 else
5715 __frac_digits_ = base::do_frac_digits();
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005716#if _WIN32
5717 if (lc->p_sign_posn == 0)
5718#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005719 if (lc->int_p_sign_posn == 0)
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005720#endif // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005721 __positive_sign_ = L"()";
5722 else
5723 {
5724 mb = mbstate_t();
5725 bb = lc->positive_sign;
Howard Hinnant866569b2011-09-28 23:39:33 +00005726#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005727 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5728#else
5729 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5730#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005731 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005732 __throw_runtime_error("locale not supported");
5733 wbe = wbuf + j;
5734 __positive_sign_.assign(wbuf, wbe);
5735 }
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005736#if _WIN32
5737 if (lc->n_sign_posn == 0)
5738#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005739 if (lc->int_n_sign_posn == 0)
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005740#endif // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005741 __negative_sign_ = L"()";
5742 else
5743 {
5744 mb = mbstate_t();
5745 bb = lc->negative_sign;
Howard Hinnant866569b2011-09-28 23:39:33 +00005746#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Sean Huntf3907e62011-07-15 05:40:33 +00005747 j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5748#else
5749 j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5750#endif
Howard Hinnantec3773c2011-12-01 20:21:04 +00005751 if (j == size_t(-1))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005752 __throw_runtime_error("locale not supported");
5753 wbe = wbuf + j;
5754 __negative_sign_.assign(wbuf, wbe);
5755 }
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005756#if _WIN32
5757 __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5758 __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5759#else // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005760 __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5761 __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00005762#endif // _WIN32
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005763}
5764
5765void __do_nothing(void*) {}
5766
5767void __throw_runtime_error(const char* msg)
5768{
Howard Hinnantd4444702010-08-11 17:04:31 +00005769#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005770 throw runtime_error(msg);
Howard Hinnantd4444702010-08-11 17:04:31 +00005771#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005772}
5773
5774template class collate<char>;
5775template class collate<wchar_t>;
5776
5777template class num_get<char>;
5778template class num_get<wchar_t>;
5779
Howard Hinnantec3773c2011-12-01 20:21:04 +00005780template struct __num_get<char>;
5781template struct __num_get<wchar_t>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005782
5783template class num_put<char>;
5784template class num_put<wchar_t>;
5785
Howard Hinnantec3773c2011-12-01 20:21:04 +00005786template struct __num_put<char>;
5787template struct __num_put<wchar_t>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005788
5789template class time_get<char>;
5790template class time_get<wchar_t>;
5791
5792template class time_get_byname<char>;
5793template class time_get_byname<wchar_t>;
5794
5795template class time_put<char>;
5796template class time_put<wchar_t>;
5797
5798template class time_put_byname<char>;
5799template class time_put_byname<wchar_t>;
5800
5801template class moneypunct<char, false>;
5802template class moneypunct<char, true>;
5803template class moneypunct<wchar_t, false>;
5804template class moneypunct<wchar_t, true>;
5805
5806template class moneypunct_byname<char, false>;
5807template class moneypunct_byname<char, true>;
5808template class moneypunct_byname<wchar_t, false>;
5809template class moneypunct_byname<wchar_t, true>;
5810
5811template class money_get<char>;
5812template class money_get<wchar_t>;
5813
5814template class __money_get<char>;
5815template class __money_get<wchar_t>;
5816
5817template class money_put<char>;
5818template class money_put<wchar_t>;
5819
5820template class __money_put<char>;
5821template class __money_put<wchar_t>;
5822
5823template class messages<char>;
5824template class messages<wchar_t>;
5825
5826template class messages_byname<char>;
5827template class messages_byname<wchar_t>;
5828
5829template class codecvt_byname<char, char, mbstate_t>;
5830template class codecvt_byname<wchar_t, char, mbstate_t>;
5831template class codecvt_byname<char16_t, char, mbstate_t>;
5832template class codecvt_byname<char32_t, char, mbstate_t>;
5833
5834template class __vector_base_common<true>;
5835
5836_LIBCPP_END_NAMESPACE_STD