mshtml: Properly report history update for location.replace call.
[wine] / dlls / msvcp60 / locale.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp.h"
24 #include "locale.h"
25 #include "errno.h"
26 #include "limits.h"
27 #include "math.h"
28 #include "stdio.h"
29
30 #include "wine/list.h"
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winnls.h"
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
38
39 char* __cdecl _Getdays(void);
40 char* __cdecl _Getmonths(void);
41 void* __cdecl _Gettnames(void);
42 unsigned int __cdecl ___lc_codepage_func(void);
43 LCID* __cdecl ___lc_handle_func(void);
44 static const locale_facet* locale__Getfacet(const locale*, MSVCP_size_t);
45
46 typedef int category;
47
48 typedef struct {
49     MSVCP_size_t id;
50 } locale_id;
51
52 typedef struct _locale__Locimp {
53     locale_facet facet;
54     locale_facet **facetvec;
55     MSVCP_size_t facet_cnt;
56     category catmask;
57     MSVCP_bool transparent;
58     basic_string_char name;
59 } locale__Locimp;
60
61 typedef struct {
62     void *timeptr;
63 } _Timevec;
64
65 typedef struct {
66     _Lockit lock;
67     basic_string_char days;
68     basic_string_char months;
69     basic_string_char oldlocname;
70     basic_string_char newlocname;
71 } _Locinfo;
72
73 typedef struct {
74     LCID handle;
75     unsigned page;
76 } _Collvec;
77
78 typedef struct {
79     locale_facet facet;
80     _Collvec coll;
81 } collate;
82
83 typedef struct {
84     locale_facet facet;
85     const char *grouping;
86     char dp;
87     char sep;
88     const char *false_name;
89     const char *true_name;
90 } numpunct_char;
91
92 typedef struct {
93     locale_facet facet;
94     const char *grouping;
95     wchar_t dp;
96     wchar_t sep;
97     const wchar_t *false_name;
98     const wchar_t *true_name;
99 } numpunct_wchar;
100
101 /* ?_Id_cnt@id@locale@std@@0HA */
102 int locale_id__Id_cnt = 0;
103
104 static locale__Locimp *global_locale;
105 static locale classic_locale;
106
107 /* ?_Clocptr@_Locimp@locale@std@@0PAV123@A */
108 /* ?_Clocptr@_Locimp@locale@std@@0PEAV123@EA */
109 locale__Locimp *locale__Locimp__Clocptr = NULL;
110
111 static char istreambuf_iterator_char_val(istreambuf_iterator_char *this)
112 {
113     if(this->strbuf && !this->got) {
114         int c = basic_streambuf_char_sgetc(this->strbuf);
115         if(c == EOF)
116             this->strbuf = NULL;
117         else
118             this->val = c;
119     }
120
121     this->got = TRUE;
122     return this->val;
123 }
124
125 static wchar_t istreambuf_iterator_wchar_val(istreambuf_iterator_wchar *this)
126 {
127     if(this->strbuf && !this->got) {
128         unsigned short c = basic_streambuf_wchar_sgetc(this->strbuf);
129         if(c == WEOF)
130             this->strbuf = NULL;
131         else
132             this->val = c;
133     }
134
135     this->got = TRUE;
136     return this->val;
137 }
138
139 static void istreambuf_iterator_char_inc(istreambuf_iterator_char *this)
140 {
141     if(!this->strbuf || basic_streambuf_char_sbumpc(this->strbuf)==EOF) {
142         this->strbuf = NULL;
143         this->got = TRUE;
144     }else {
145         this->got = FALSE;
146         istreambuf_iterator_char_val(this);
147     }
148 }
149
150 static void istreambuf_iterator_wchar_inc(istreambuf_iterator_wchar *this)
151 {
152     if(!this->strbuf || basic_streambuf_wchar_sbumpc(this->strbuf)==WEOF) {
153         this->strbuf = NULL;
154         this->got = TRUE;
155     }else {
156         this->got = FALSE;
157         istreambuf_iterator_wchar_val(this);
158     }
159 }
160
161 static void ostreambuf_iterator_char_put(ostreambuf_iterator_char *this, char ch)
162 {
163     if(this->failed || basic_streambuf_char_sputc(this->strbuf, ch)==EOF)
164         this->failed = TRUE;
165 }
166
167 static void ostreambuf_iterator_wchar_put(ostreambuf_iterator_wchar *this, wchar_t ch)
168 {
169     if(this->failed || basic_streambuf_wchar_sputc(this->strbuf, ch)==WEOF)
170         this->failed = TRUE;
171 }
172
173 /* ??1facet@locale@std@@UAE@XZ */
174 /* ??1facet@locale@std@@UEAA@XZ */
175 DEFINE_THISCALL_WRAPPER(locale_facet_dtor, 4)
176 void __thiscall locale_facet_dtor(locale_facet *this)
177 {
178     TRACE("(%p)\n", this);
179 }
180
181 DEFINE_THISCALL_WRAPPER(locale_facet_vector_dtor, 8)
182 #define call_locale_facet_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0, \
183         locale_facet*, (locale_facet*, unsigned int), (this, flags))
184 locale_facet* __thiscall locale_facet_vector_dtor(locale_facet *this, unsigned int flags)
185 {
186     TRACE("(%p %x)\n", this, flags);
187     if(flags & 2) {
188         /* we have an array, with the number of elements stored before the first object */
189         INT_PTR i, *ptr = (INT_PTR *)this-1;
190
191         for(i=*ptr-1; i>=0; i--)
192             locale_facet_dtor(this+i);
193         MSVCRT_operator_delete(ptr);
194     } else {
195         locale_facet_dtor(this);
196         if(flags & 1)
197             MSVCRT_operator_delete(this);
198     }
199
200     return this;
201 }
202
203 typedef struct
204 {
205     locale_facet *fac;
206     struct list entry;
207 } facets_elem;
208 static struct list lazy_facets = LIST_INIT(lazy_facets);
209
210 /* Not exported from msvcp90 */
211 /* ?facet_Register@facet@locale@std@@CAXPAV123@@Z */
212 /* ?facet_Register@facet@locale@std@@CAXPEAV123@@Z */
213 static void locale_facet_register(locale_facet *add)
214 {
215     facets_elem *head = MSVCRT_operator_new(sizeof(*head));
216     if(!head) {
217         ERR("Out of memory\n");
218         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
219     }
220
221     head->fac = add;
222     list_add_head(&lazy_facets, &head->entry);
223 }
224
225 /* Not exported from msvcp90 */
226 /* ??_7facet@locale@std@@6B@ */
227 extern const vtable_ptr MSVCP_locale_facet_vtable;
228
229 /* ??Bid@locale@std@@QAEIXZ */
230 /* ??Bid@locale@std@@QEAA_KXZ */
231 DEFINE_THISCALL_WRAPPER(locale_id_operator_size_t, 4)
232 MSVCP_size_t __thiscall locale_id_operator_size_t(locale_id *this)
233 {
234     _Lockit lock;
235
236     TRACE("(%p)\n", this);
237
238     if(!this->id) {
239         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
240         this->id = ++locale_id__Id_cnt;
241         _Lockit_dtor(&lock);
242     }
243
244     return this->id;
245 }
246
247 /* ??_Ffacet@locale@std@@QAEXXZ */
248 /* ??_Ffacet@locale@std@@QEAAXXZ */
249 DEFINE_THISCALL_WRAPPER(locale_facet_ctor, 4)
250 locale_facet* __thiscall locale_facet_ctor(locale_facet *this)
251 {
252     TRACE("(%p)\n", this);
253     this->vtable = &MSVCP_locale_facet_vtable;
254     this->refs = 0;
255     return this;
256 }
257
258 /* ??0facet@locale@std@@IAE@I@Z */
259 /* ??0facet@locale@std@@IEAA@_K@Z */
260 DEFINE_THISCALL_WRAPPER(locale_facet_ctor_refs, 8)
261 locale_facet* __thiscall locale_facet_ctor_refs(locale_facet *this, MSVCP_size_t refs)
262 {
263     TRACE("(%p %lu)\n", this, refs);
264     this->vtable = &MSVCP_locale_facet_vtable;
265     this->refs = refs;
266     return this;
267 }
268
269 /* ?_Incref@facet@locale@std@@QAEXXZ */
270 /* ?_Incref@facet@locale@std@@QEAAXXZ */
271 DEFINE_THISCALL_WRAPPER(locale_facet__Incref, 4)
272 void __thiscall locale_facet__Incref(locale_facet *this)
273 {
274     _Lockit lock;
275
276     TRACE("(%p)\n", this);
277
278     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
279     this->refs++;
280     _Lockit_dtor(&lock);
281 }
282
283 /* ?_Decref@facet@locale@std@@QAEPAV123@XZ */
284 /* ?_Decref@facet@locale@std@@QEAAPEAV123@XZ */
285 DEFINE_THISCALL_WRAPPER(locale_facet__Decref, 4)
286 locale_facet* __thiscall locale_facet__Decref(locale_facet *this)
287 {
288     _Lockit lock;
289     locale_facet *ret;
290
291     TRACE("(%p)\n", this);
292
293     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
294     if(this->refs)
295         this->refs--;
296
297     ret = this->refs ? NULL : this;
298     _Lockit_dtor(&lock);
299
300     return ret;
301 }
302
303 /* ??0_Timevec@std@@QAE@ABV01@@Z */
304 /* ??0_Timevec@std@@QEAA@AEBV01@@Z */
305 /* This copy constructor modifies copied object */
306 DEFINE_THISCALL_WRAPPER(_Timevec_copy_ctor, 8)
307 _Timevec* __thiscall _Timevec_copy_ctor(_Timevec *this, _Timevec *copy)
308 {
309     TRACE("(%p %p)\n", this, copy);
310     this->timeptr = copy->timeptr;
311     copy->timeptr = NULL;
312     return this;
313 }
314
315 /* ??0_Timevec@std@@QAE@PAX@Z */
316 /* ??0_Timevec@std@@QEAA@PEAX@Z */
317 DEFINE_THISCALL_WRAPPER(_Timevec_ctor_timeptr, 8)
318 _Timevec* __thiscall _Timevec_ctor_timeptr(_Timevec *this, void *timeptr)
319 {
320     TRACE("(%p %p)\n", this, timeptr);
321     this->timeptr = timeptr;
322     return this;
323 }
324
325 /* ??_F_Timevec@std@@QAEXXZ */
326 /* ??_F_Timevec@std@@QEAAXXZ */
327 DEFINE_THISCALL_WRAPPER(_Timevec_ctor, 4)
328 _Timevec* __thiscall _Timevec_ctor(_Timevec *this)
329 {
330     TRACE("(%p)\n", this);
331     this->timeptr = NULL;
332     return this;
333 }
334
335 /* ??1_Timevec@std@@QAE@XZ */
336 /* ??1_Timevec@std@@QEAA@XZ */
337 DEFINE_THISCALL_WRAPPER(_Timevec_dtor, 4)
338 void __thiscall _Timevec_dtor(_Timevec *this)
339 {
340     TRACE("(%p)\n", this);
341     free(this->timeptr);
342 }
343
344 /* ??4_Timevec@std@@QAEAAV01@ABV01@@Z */
345 /* ??4_Timevec@std@@QEAAAEAV01@AEBV01@@Z */
346 DEFINE_THISCALL_WRAPPER(_Timevec_op_assign, 8)
347 _Timevec* __thiscall _Timevec_op_assign(_Timevec *this, _Timevec *right)
348 {
349     TRACE("(%p %p)\n", this, right);
350     this->timeptr = right->timeptr;
351     right->timeptr = NULL;
352     return this;
353 }
354
355 /* ?_Getptr@_Timevec@std@@QBEPAXXZ */
356 /* ?_Getptr@_Timevec@std@@QEBAPEAXXZ */
357 DEFINE_THISCALL_WRAPPER(_Timevec__Getptr, 4)
358 void* __thiscall _Timevec__Getptr(_Timevec *this)
359 {
360     TRACE("(%p)\n", this);
361     return this->timeptr;
362 }
363
364 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@HPBD@Z */
365 /* ?_Locinfo_ctor@_Locinfo@std@@SAXPEAV12@HPEBD@Z */
366 static _Locinfo* _Locinfo__Locinfo_ctor_cat_cstr(_Locinfo *locinfo, int category, const char *locstr)
367 {
368     const char *locale = NULL;
369
370     /* This function is probably modifying more global objects */
371     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
372
373     if(!locstr)
374         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
375
376     _Lockit_ctor_locktype(&locinfo->lock, _LOCK_LOCALE);
377     basic_string_char_ctor_cstr(&locinfo->days, "");
378     basic_string_char_ctor_cstr(&locinfo->months, "");
379     basic_string_char_ctor_cstr(&locinfo->oldlocname, setlocale(LC_ALL, NULL));
380
381     if(category)
382         locale = setlocale(LC_ALL, locstr);
383     else
384         locale = setlocale(LC_ALL, NULL);
385
386     if(locale)
387         basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
388     else
389         basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
390
391     return locinfo;
392 }
393
394 /* ??0_Locinfo@std@@QAE@HPBD@Z */
395 /* ??0_Locinfo@std@@QEAA@HPEBD@Z */
396 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cat_cstr, 12)
397 _Locinfo* __thiscall _Locinfo_ctor_cat_cstr(_Locinfo *this, int category, const char *locstr)
398 {
399     return _Locinfo__Locinfo_ctor_cat_cstr(this, category, locstr);
400 }
401
402 /* ??0_Locinfo@std@@QAE@PBD@Z */
403 /* ??0_Locinfo@std@@QEAA@PEBD@Z */
404 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor_cstr, 8)
405 _Locinfo* __thiscall _Locinfo_ctor_cstr(_Locinfo *this, const char *locstr)
406 {
407     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, locstr);
408 }
409
410 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z */
411 /* ?_Locinfo_dtor@_Locinfo@std@@SAXPEAV12@@Z */
412 static void _Locinfo__Locinfo_dtor(_Locinfo *locinfo)
413 {
414     TRACE("(%p)\n", locinfo);
415
416     setlocale(LC_ALL, basic_string_char_c_str(&locinfo->oldlocname));
417     basic_string_char_dtor(&locinfo->days);
418     basic_string_char_dtor(&locinfo->months);
419     basic_string_char_dtor(&locinfo->oldlocname);
420     basic_string_char_dtor(&locinfo->newlocname);
421     _Lockit_dtor(&locinfo->lock);
422 }
423
424 /* ??_F_Locinfo@std@@QAEXXZ */
425 /* ??_F_Locinfo@std@@QEAAXXZ */
426 DEFINE_THISCALL_WRAPPER(_Locinfo_ctor, 4)
427 _Locinfo* __thiscall _Locinfo_ctor(_Locinfo *this)
428 {
429     return _Locinfo__Locinfo_ctor_cat_cstr(this, 1/*FIXME*/, "C");
430 }
431
432 /* ??1_Locinfo@std@@QAE@XZ */
433 /* ??1_Locinfo@std@@QEAA@XZ */
434 DEFINE_THISCALL_WRAPPER(_Locinfo_dtor, 4)
435 void __thiscall _Locinfo_dtor(_Locinfo *this)
436 {
437     _Locinfo__Locinfo_dtor(this);
438 }
439
440 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAAV12@PAV12@HPBD@Z */
441 /* ?_Locinfo_Addcats@_Locinfo@std@@SAAEAV12@PEAV12@HPEBD@Z */
442 static _Locinfo* _Locinfo__Locinfo_Addcats(_Locinfo *locinfo, int category, const char *locstr)
443 {
444     const char *locale = NULL;
445
446     /* This function is probably modifying more global objects */
447     FIXME("(%p %d %s) semi-stub\n", locinfo, category, locstr);
448     if(!locstr)
449         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
450
451     basic_string_char_dtor(&locinfo->newlocname);
452
453     if(category)
454         locale = setlocale(LC_ALL, locstr);
455     else
456         locale = setlocale(LC_ALL, NULL);
457
458     if(locale)
459         basic_string_char_ctor_cstr(&locinfo->newlocname, locale);
460     else
461         basic_string_char_ctor_cstr(&locinfo->newlocname, "*");
462
463     return locinfo;
464 }
465
466 /* ?_Addcats@_Locinfo@std@@QAEAAV12@HPBD@Z */
467 /* ?_Addcats@_Locinfo@std@@QEAAAEAV12@HPEBD@Z */
468 DEFINE_THISCALL_WRAPPER(_Locinfo__Addcats, 12)
469 _Locinfo* __thiscall _Locinfo__Addcats(_Locinfo *this, int category, const char *locstr)
470 {
471     return _Locinfo__Locinfo_Addcats(this, category, locstr);
472 }
473
474 /* _Getcoll */
475 ULONGLONG __cdecl _Getcoll(void)
476 {
477     union {
478         _Collvec collvec;
479         ULONGLONG ull;
480     } ret;
481     _locale_t locale = _get_current_locale();
482
483     TRACE("\n");
484
485     ret.collvec.page = locale->locinfo->lc_collate_cp;
486     ret.collvec.handle = locale->locinfo->lc_handle[LC_COLLATE];
487     _free_locale(locale);
488     return ret.ull;
489 }
490
491 /* ?_Getcoll@_Locinfo@std@@QBE?AU_Collvec@@XZ */
492 /* ?_Getcoll@_Locinfo@std@@QEBA?AU_Collvec@@XZ */
493 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcoll, 8)
494 _Collvec* __thiscall _Locinfo__Getcoll(const _Locinfo *this, _Collvec *ret)
495 {
496     ULONGLONG ull = _Getcoll();
497     memcpy(ret, &ull, sizeof(ull));
498     return ret;
499 }
500
501 /* _Getctype */
502 _Ctypevec* __cdecl _Getctype(_Ctypevec *ret)
503 {
504     _locale_t locale = _get_current_locale();
505     short *table;
506
507     TRACE("\n");
508
509     ret->page = locale->locinfo->lc_codepage;
510     ret->handle = locale->locinfo->lc_handle[LC_COLLATE];
511     ret->delfl = TRUE;
512     table = malloc(sizeof(short[256]));
513     if(!table) {
514         _free_locale(locale);
515         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
516     }
517     memcpy(table, locale->locinfo->pctype, sizeof(short[256]));
518     ret->table = table;
519     _free_locale(locale);
520     return ret;
521 }
522
523 /* ?_Getctype@_Locinfo@std@@QBE?AU_Ctypevec@@XZ */
524 /* ?_Getctype@_Locinfo@std@@QEBA?AU_Ctypevec@@XZ */
525 DEFINE_THISCALL_WRAPPER(_Locinfo__Getctype, 8)
526 _Ctypevec* __thiscall _Locinfo__Getctype(const _Locinfo *this, _Ctypevec *ret)
527 {
528     return _Getctype(ret);
529 }
530
531 /* _Getcvt */
532 ULONGLONG __cdecl _Getcvt(void)
533 {
534     _locale_t locale = _get_current_locale();
535     union {
536         _Cvtvec cvtvec;
537         ULONGLONG ull;
538     } ret;
539
540     TRACE("\n");
541
542     ret.cvtvec.page = locale->locinfo->lc_codepage;
543     ret.cvtvec.handle = locale->locinfo->lc_handle[LC_CTYPE];
544     _free_locale(locale);
545     return ret.ull;
546 }
547
548 /* ?_Getcvt@_Locinfo@std@@QBE?AU_Cvtvec@@XZ */
549 /* ?_Getcvt@_Locinfo@std@@QEBA?AU_Cvtvec@@XZ */
550 DEFINE_THISCALL_WRAPPER(_Locinfo__Getcvt, 8)
551 _Cvtvec* __thiscall _Locinfo__Getcvt(const _Locinfo *this, _Cvtvec *ret)
552 {
553     ULONGLONG ull = _Getcvt();
554     memcpy(ret, &ull, sizeof(ull));
555     return ret;
556 }
557
558 /* ?_Getdays@_Locinfo@std@@QBEPBDXZ */
559 /* ?_Getdays@_Locinfo@std@@QEBAPEBDXZ */
560 DEFINE_THISCALL_WRAPPER(_Locinfo__Getdays, 4)
561 const char* __thiscall _Locinfo__Getdays(_Locinfo *this)
562 {
563     char *days = _Getdays();
564
565     TRACE("(%p)\n", this);
566
567     if(days) {
568         basic_string_char_dtor(&this->days);
569         basic_string_char_ctor_cstr(&this->days, days);
570         free(days);
571     }
572
573     return this->days.size ? basic_string_char_c_str(&this->days) :
574         ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
575 }
576
577 /* ?_Getmonths@_Locinfo@std@@QBEPBDXZ */
578 /* ?_Getmonths@_Locinfo@std@@QEBAPEBDXZ */
579 DEFINE_THISCALL_WRAPPER(_Locinfo__Getmonths, 4)
580 const char* __thiscall _Locinfo__Getmonths(_Locinfo *this)
581 {
582     char *months = _Getmonths();
583
584     TRACE("(%p)\n", this);
585
586     if(months) {
587         basic_string_char_dtor(&this->months);
588         basic_string_char_ctor_cstr(&this->months, months);
589         free(months);
590     }
591
592     return this->months.size ? basic_string_char_c_str(&this->months) :
593         ":Jan:January:Feb:February:Mar:March:Apr:April:May:May:Jun:June:Jul:July"
594         ":Aug:August:Sep:September:Oct:October:Nov:November:Dec:December";
595 }
596
597 /* ?_Getfalse@_Locinfo@std@@QBEPBDXZ */
598 /* ?_Getfalse@_Locinfo@std@@QEBAPEBDXZ */
599 DEFINE_THISCALL_WRAPPER(_Locinfo__Getfalse, 4)
600 const char* __thiscall _Locinfo__Getfalse(const _Locinfo *this)
601 {
602     TRACE("(%p)\n", this);
603     return "false";
604 }
605
606 /* ?_Gettrue@_Locinfo@std@@QBEPBDXZ */
607 /* ?_Gettrue@_Locinfo@std@@QEBAPEBDXZ */
608 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettrue, 4)
609 const char* __thiscall _Locinfo__Gettrue(const _Locinfo *this)
610 {
611     TRACE("(%p)\n", this);
612     return "true";
613 }
614
615 /* ?_Getlconv@_Locinfo@std@@QBEPBUlconv@@XZ */
616 /* ?_Getlconv@_Locinfo@std@@QEBAPEBUlconv@@XZ */
617 DEFINE_THISCALL_WRAPPER(_Locinfo__Getlconv, 4)
618 const struct lconv* __thiscall _Locinfo__Getlconv(const _Locinfo *this)
619 {
620     TRACE("(%p)\n", this);
621     return localeconv();
622 }
623
624 /* ?_Getname@_Locinfo@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
625 /* ?_Getname@_Locinfo@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
626 DEFINE_THISCALL_WRAPPER(_Locinfo__Getname, 8)
627 basic_string_char* __thiscall _Locinfo__Getname(const _Locinfo *this, basic_string_char *ret)
628 {
629     TRACE("(%p)\n", this);
630
631     basic_string_char_copy_ctor(ret, &this->newlocname);
632     return ret;
633 }
634
635 /* ?_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ */
636 /* ?_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ */
637 DEFINE_THISCALL_WRAPPER(_Locinfo__Gettnames, 8)
638 _Timevec*__thiscall _Locinfo__Gettnames(const _Locinfo *this, _Timevec *ret)
639 {
640     TRACE("(%p)\n", this);
641
642     _Timevec_ctor_timeptr(ret, _Gettnames());
643     return ret;
644 }
645
646 /* ?id@?$collate@D@std@@2V0locale@2@A */
647 locale_id collate_char_id = {0};
648
649 /* ??_7?$collate@D@std@@6B@ */
650 extern const vtable_ptr MSVCP_collate_char_vtable;
651
652 /* ?_Init@?$collate@D@std@@IAEXABV_Locinfo@2@@Z */
653 /* ?_Init@?$collate@D@std@@IEAAXAEBV_Locinfo@2@@Z */
654 DEFINE_THISCALL_WRAPPER(collate_char__Init, 8)
655 void __thiscall collate_char__Init(collate *this, const _Locinfo *locinfo)
656 {
657     TRACE("(%p %p)\n", this, locinfo);
658     _Locinfo__Getcoll(locinfo, &this->coll);
659 }
660
661 /* ??0?$collate@D@std@@IAE@PBDI@Z */
662 /* ??0?$collate@D@std@@IEAA@PEBD_K@Z */
663 static collate* collate_char_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
664 {
665     _Locinfo locinfo;
666
667     TRACE("(%p %s %lu)\n", this, name, refs);
668
669     locale_facet_ctor_refs(&this->facet, refs);
670     this->facet.vtable = &MSVCP_collate_char_vtable;
671
672     _Locinfo_ctor_cstr(&locinfo, name);
673     collate_char__Init(this, &locinfo);
674     _Locinfo_dtor(&locinfo);
675     return this;
676 }
677
678 /* ??0?$collate@D@std@@QAE@ABV_Locinfo@1@I@Z */
679 /* ??0?$collate@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
680 DEFINE_THISCALL_WRAPPER(collate_char_ctor_locinfo, 12)
681 collate* __thiscall collate_char_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
682 {
683     TRACE("(%p %p %lu)\n", this, locinfo, refs);
684
685     locale_facet_ctor_refs(&this->facet, refs);
686     this->facet.vtable = &MSVCP_collate_char_vtable;
687     collate_char__Init(this, locinfo);
688     return this;
689 }
690
691 /* ??0?$collate@D@std@@QAE@I@Z */
692 /* ??0?$collate@D@std@@QEAA@_K@Z */
693 DEFINE_THISCALL_WRAPPER(collate_char_ctor_refs, 8)
694 collate* __thiscall collate_char_ctor_refs(collate *this, MSVCP_size_t refs)
695 {
696     return collate_char_ctor_name(this, "C", refs);
697 }
698
699 /* ??1?$collate@D@std@@MAE@XZ */
700 /* ??1?$collate@D@std@@MEAA@XZ */
701 static void collate_char_dtor(collate *this)
702 {
703     TRACE("(%p)\n", this);
704 }
705
706 DEFINE_THISCALL_WRAPPER(collate_char_vector_dtor, 8)
707 collate* __thiscall collate_char_vector_dtor(collate *this, unsigned int flags)
708 {
709     TRACE("(%p %x)\n", this, flags);
710     if(flags & 2) {
711         /* we have an array, with the number of elements stored before the first object */
712         INT_PTR i, *ptr = (INT_PTR *)this-1;
713
714         for(i=*ptr-1; i>=0; i--)
715             collate_char_dtor(this+i);
716         MSVCRT_operator_delete(ptr);
717     } else {
718         collate_char_dtor(this);
719         if(flags & 1)
720             MSVCRT_operator_delete(this);
721     }
722
723     return this;
724 }
725
726 /* ??_F?$collate@D@std@@QAEXXZ */
727 /* ??_F?$collate@D@std@@QEAAXXZ */
728 DEFINE_THISCALL_WRAPPER(collate_char_ctor, 4)
729 collate* __thiscall collate_char_ctor(collate *this)
730 {
731     return collate_char_ctor_name(this, "C", 0);
732 }
733
734 /* _Strcoll */
735 int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2,
736         const char *last2, const _Collvec *coll)
737 {
738     LCID lcid;
739
740     TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2));
741
742     if(coll)
743         lcid = coll->handle;
744     else
745         lcid = ___lc_handle_func()[LC_COLLATE];
746     return CompareStringA(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
747 }
748
749 /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */
750 /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */
751 DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20)
752 #define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
753         (const collate*, const char*, const char*, const char*, const char*), \
754         (this, first1, last1, first2, last2))
755 int __thiscall collate_char_do_compare(const collate *this, const char *first1,
756         const char *last1, const char *first2, const char *last2)
757 {
758     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
759     return _Strcoll(first1, last1, first2, last2, &this->coll);
760 }
761
762 /* ?compare@?$collate@D@std@@QBEHPBD000@Z */
763 /* ?compare@?$collate@D@std@@QEBAHPEBD000@Z */
764 DEFINE_THISCALL_WRAPPER(collate_char_compare, 20)
765 int __thiscall collate_char_compare(const collate *this, const char *first1,
766         const char *last1, const char *first2, const char *last2)
767 {
768     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
769     return call_collate_char_do_compare(this, first1, last1, first2, last2);
770 }
771
772 /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */
773 /* ?do_hash@?$collate@D@std@@MEBAJPEBD0@Z */
774 DEFINE_THISCALL_WRAPPER(collate_char_do_hash, 12)
775 #define call_collate_char_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
776         (const collate*, const char*, const char*), (this, first, last))
777 LONG __thiscall collate_char_do_hash(const collate *this,
778         const char *first, const char *last)
779 {
780     ULONG ret = 0;
781
782     TRACE("(%p %p %p)\n", this, first, last);
783
784     for(; first<last; first++)
785         ret = (ret<<8 | ret>>24) + *first;
786     return ret;
787 }
788
789 /* ?hash@?$collate@D@std@@QBEJPBD0@Z */
790 /* ?hash@?$collate@D@std@@QEBAJPEBD0@Z */
791 DEFINE_THISCALL_WRAPPER(collate_char_hash, 12)
792 LONG __thiscall collate_char_hash(const collate *this,
793         const char *first, const char *last)
794 {
795     TRACE("(%p %p %p)\n", this, first, last);
796     return call_collate_char_do_hash(this, first, last);
797 }
798
799 /* ?do_transform@?$collate@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
800 /* ?do_transform@?$collate@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
801 DEFINE_THISCALL_WRAPPER(collate_char_do_transform, 16)
802 basic_string_char* __thiscall collate_char_do_transform(const collate *this,
803         basic_string_char *ret, const char *first, const char *last)
804 {
805     FIXME("(%p %p %p) stub\n", this, first, last);
806     return ret;
807 }
808
809 /* ?transform@?$collate@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PBD0@Z */
810 /* ?transform@?$collate@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@PEBD0@Z */
811 DEFINE_THISCALL_WRAPPER(collate_char_transform, 16)
812 basic_string_char* __thiscall collate_char_transform(const collate *this,
813         basic_string_char *ret, const char *first, const char *last)
814 {
815     FIXME("(%p %p %p) stub\n", this, first, last);
816     return ret;
817 }
818
819 /* ?id@?$collate@G@std@@2V0locale@2@A */
820 locale_id collate_short_id = {0};
821
822 /* ??_7?$collate@_W@std@@6B@ */
823 extern const vtable_ptr MSVCP_collate_wchar_vtable;
824 /* ??_7?$collate@G@std@@6B@ */
825 extern const vtable_ptr MSVCP_collate_short_vtable;
826
827 /* ?_Init@?$collate@_W@std@@IAEXABV_Locinfo@2@@Z */
828 /* ?_Init@?$collate@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
829 /* ?_Init@?$collate@G@std@@IAEXABV_Locinfo@2@@Z */
830 /* ?_Init@?$collate@G@std@@IEAAXAEBV_Locinfo@2@@Z */
831 DEFINE_THISCALL_WRAPPER(collate_wchar__Init, 8)
832 void __thiscall collate_wchar__Init(collate *this, const _Locinfo *locinfo)
833 {
834     TRACE("(%p %p)\n", this, locinfo);
835     _Locinfo__Getcoll(locinfo, &this->coll);
836 }
837
838 /* ??0?$collate@_W@std@@IAE@PBDI@Z */
839 /* ??0?$collate@_W@std@@IEAA@PEBD_K@Z */
840 static collate* collate_wchar_ctor_name(collate *this, const char *name, MSVCP_size_t refs)
841 {
842     _Locinfo locinfo;
843
844     TRACE("(%p %s %lu)\n", this, name, refs);
845
846     locale_facet_ctor_refs(&this->facet, refs);
847     this->facet.vtable = &MSVCP_collate_wchar_vtable;
848
849     _Locinfo_ctor_cstr(&locinfo, name);
850     collate_wchar__Init(this, &locinfo);
851     _Locinfo_dtor(&locinfo);
852     return this;
853 }
854
855 /* ??0?$collate@_W@std@@QAE@ABV_Locinfo@1@I@Z */
856 /* ??0?$collate@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
857 static collate* collate_wchar_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
858 {
859     TRACE("(%p %p %lu)\n", this, locinfo, refs);
860
861     locale_facet_ctor_refs(&this->facet, refs);
862     this->facet.vtable = &MSVCP_collate_wchar_vtable;
863     collate_wchar__Init(this, locinfo);
864     return this;
865 }
866
867 /* ??0?$collate@G@std@@QAE@ABV_Locinfo@1@I@Z */
868 /* ??0?$collate@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
869 DEFINE_THISCALL_WRAPPER(collate_short_ctor_locinfo, 12)
870 collate* __thiscall collate_short_ctor_locinfo(collate *this, _Locinfo *locinfo, MSVCP_size_t refs)
871 {
872     collate *ret = collate_wchar_ctor_locinfo(this, locinfo, refs);
873     ret->facet.vtable = &MSVCP_collate_short_vtable;
874     return ret;
875 }
876
877 /* ??0?$collate@_W@std@@QAE@I@Z */
878 /* ??0?$collate@_W@std@@QEAA@_K@Z */
879 static collate* collate_wchar_ctor_refs(collate *this, MSVCP_size_t refs)
880 {
881     return collate_wchar_ctor_name(this, "C", refs);
882 }
883
884 /* ??0?$collate@G@std@@QAE@I@Z */
885 /* ??0?$collate@G@std@@QEAA@_K@Z */
886 DEFINE_THISCALL_WRAPPER(collate_short_ctor_refs, 8)
887 collate* __thiscall collate_short_ctor_refs(collate *this, MSVCP_size_t refs)
888 {
889     collate *ret = collate_wchar_ctor_refs(this, refs);
890     ret->facet.vtable = &MSVCP_collate_short_vtable;
891     return ret;
892 }
893
894 /* ??1?$collate@_W@std@@MAE@XZ */
895 /* ??1?$collate@_W@std@@MEAA@XZ */
896 /* ??1?$collate@G@std@@MAE@XZ */
897 /* ??1?$collate@G@std@@MEAA@XZ */
898 static void collate_wchar_dtor(collate *this)
899 {
900     TRACE("(%p)\n", this);
901 }
902
903 DEFINE_THISCALL_WRAPPER(collate_wchar_vector_dtor, 8)
904 collate* __thiscall collate_wchar_vector_dtor(collate *this, unsigned int flags)
905 {
906     TRACE("(%p %x)\n", this, flags);
907     if(flags & 2) {
908         /* we have an array, with the number of elements stored before the first object */
909         INT_PTR i, *ptr = (INT_PTR *)this-1;
910
911         for(i=*ptr-1; i>=0; i--)
912             collate_wchar_dtor(this+i);
913         MSVCRT_operator_delete(ptr);
914     } else {
915         collate_wchar_dtor(this);
916         if(flags & 1)
917             MSVCRT_operator_delete(this);
918     }
919
920     return this;
921 }
922
923 /* ??_F?$collate@_W@std@@QAEXXZ */
924 /* ??_F?$collate@_W@std@@QEAAXXZ */
925 static collate* collate_wchar_ctor(collate *this)
926 {
927     return collate_wchar_ctor_name(this, "C", 0);
928 }
929
930 /* ??_F?$collate@G@std@@QAEXXZ */
931 /* ??_F?$collate@G@std@@QEAAXXZ */
932 DEFINE_THISCALL_WRAPPER(collate_short_ctor, 4)
933 collate* __thiscall collate_short_ctor(collate *this)
934 {
935     collate *ret = collate_wchar_ctor(this);
936     ret->facet.vtable = &MSVCP_collate_short_vtable;
937     return ret;
938 }
939
940 /* _Wcscoll */
941 static int _Wcscoll(const wchar_t *first1, const wchar_t *last1, const wchar_t *first2,
942         const wchar_t *last2, const _Collvec *coll)
943 {
944     LCID lcid;
945
946     TRACE("(%s %s)\n", debugstr_wn(first1, last1-first1), debugstr_wn(first2, last2-first2));
947
948     if(coll)
949         lcid = coll->handle;
950     else
951         lcid = ___lc_handle_func()[LC_COLLATE];
952     return CompareStringW(lcid, 0, first1, last1-first1, first2, last2-first2)-CSTR_EQUAL;
953 }
954
955 /* ?do_compare@?$collate@_W@std@@MBEHPB_W000@Z */
956 /* ?do_compare@?$collate@_W@std@@MEBAHPEB_W000@Z */
957 /* ?do_compare@?$collate@G@std@@MBEHPBG000@Z */
958 /* ?do_compare@?$collate@G@std@@MEBAHPEBG000@Z */
959 DEFINE_THISCALL_WRAPPER(collate_wchar_do_compare, 20)
960 #define call_collate_wchar_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \
961         (const collate*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*), \
962         (this, first1, last1, first2, last2))
963 int __thiscall collate_wchar_do_compare(const collate *this, const wchar_t *first1,
964         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
965 {
966     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
967     return _Wcscoll(first1, last1, first2, last2, &this->coll);
968 }
969
970 /* ?compare@?$collate@_W@std@@QBEHPB_W000@Z */
971 /* ?compare@?$collate@_W@std@@QEBAHPEB_W000@Z */
972 /* ?compare@?$collate@G@std@@QBEHPBG000@Z */
973 /* ?compare@?$collate@G@std@@QEBAHPEBG000@Z */
974 DEFINE_THISCALL_WRAPPER(collate_wchar_compare, 20)
975 int __thiscall collate_wchar_compare(const collate *this, const wchar_t *first1,
976         const wchar_t *last1, const wchar_t *first2, const wchar_t *last2)
977 {
978     TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2);
979     return call_collate_wchar_do_compare(this, first1, last1, first2, last2);
980 }
981
982 /* ?do_hash@?$collate@_W@std@@MBEJPB_W0@Z */
983 /* ?do_hash@?$collate@_W@std@@MEBAJPEB_W0@Z */
984 /* ?do_hash@?$collate@G@std@@MBEJPBG0@Z */
985 /* ?do_hash@?$collate@G@std@@MEBAJPEBG0@Z */
986 DEFINE_THISCALL_WRAPPER(collate_wchar_do_hash, 12)
987 #define call_collate_wchar_do_hash(this, first, last) CALL_VTBL_FUNC(this, 12, LONG, \
988         (const collate*, const wchar_t*, const wchar_t*), (this, first, last))
989 LONG __thiscall collate_wchar_do_hash(const collate *this,
990         const wchar_t *first, const wchar_t *last)
991 {
992     ULONG ret = 0;
993
994     TRACE("(%p %p %p)\n", this, first, last);
995
996     for(; first<last; first++)
997         ret = (ret<<8 | ret>>24) + *first;
998     return ret;
999 }
1000
1001 /* ?hash@?$collate@_W@std@@QBEJPB_W0@Z */
1002 /* ?hash@?$collate@_W@std@@QEBAJPEB_W0@Z */
1003 /* ?hash@?$collate@G@std@@QBEJPBG0@Z */
1004 /* ?hash@?$collate@G@std@@QEBAJPEBG0@Z */
1005 DEFINE_THISCALL_WRAPPER(collate_wchar_hash, 12)
1006 LONG __thiscall collate_wchar_hash(const collate *this,
1007         const wchar_t *first, const wchar_t *last)
1008 {
1009     TRACE("(%p %p %p)\n", this, first, last);
1010     return call_collate_wchar_do_hash(this, first, last);
1011 }
1012
1013 /* ?do_transform@?$collate@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1014 /* ?do_transform@?$collate@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1015 /* ?do_transform@?$collate@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1016 /* ?do_transform@?$collate@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1017 DEFINE_THISCALL_WRAPPER(collate_wchar_do_transform, 16)
1018 basic_string_wchar* __thiscall collate_wchar_do_transform(const collate *this,
1019         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1020 {
1021     FIXME("(%p %p %p) stub\n", this, first, last);
1022     return ret;
1023 }
1024
1025 /* ?transform@?$collate@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PB_W0@Z */
1026 /* ?transform@?$collate@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@PEB_W0@Z */
1027 /* ?transform@?$collate@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PBG0@Z */
1028 /* ?transform@?$collate@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@PEBG0@Z */
1029 DEFINE_THISCALL_WRAPPER(collate_wchar_transform, 16)
1030 basic_string_wchar* __thiscall collate_wchar_transform(const collate *this,
1031         basic_string_wchar *ret, const wchar_t *first, const wchar_t *last)
1032 {
1033     FIXME("(%p %p %p) stub\n", this, first, last);
1034     return ret;
1035 }
1036
1037 /* ??_7ctype_base@std@@6B@ */
1038 extern const vtable_ptr MSVCP_ctype_base_vtable;
1039
1040 /* ??0ctype_base@std@@QAE@I@Z */
1041 /* ??0ctype_base@std@@QEAA@_K@Z */
1042 DEFINE_THISCALL_WRAPPER(ctype_base_ctor_refs, 8)
1043 ctype_base* __thiscall ctype_base_ctor_refs(ctype_base *this, MSVCP_size_t refs)
1044 {
1045     TRACE("(%p %lu)\n", this, refs);
1046     locale_facet_ctor_refs(&this->facet, refs);
1047     this->facet.vtable = &MSVCP_ctype_base_vtable;
1048     return this;
1049 }
1050
1051 /* ??_Fctype_base@std@@QAEXXZ */
1052 /* ??_Fctype_base@std@@QEAAXXZ */
1053 DEFINE_THISCALL_WRAPPER(ctype_base_ctor, 4)
1054 ctype_base* __thiscall ctype_base_ctor(ctype_base *this)
1055 {
1056     TRACE("(%p)\n", this);
1057     locale_facet_ctor_refs(&this->facet, 0);
1058     this->facet.vtable = &MSVCP_ctype_base_vtable;
1059     return this;
1060 }
1061
1062 /* ??1ctype_base@std@@UAE@XZ */
1063 /* ??1ctype_base@std@@UEAA@XZ */
1064 DEFINE_THISCALL_WRAPPER(ctype_base_dtor, 4)
1065 void __thiscall ctype_base_dtor(ctype_base *this)
1066 {
1067     TRACE("(%p)\n", this);
1068 }
1069
1070 DEFINE_THISCALL_WRAPPER(ctype_base_vector_dtor, 8)
1071 ctype_base* __thiscall ctype_base_vector_dtor(ctype_base *this, unsigned int flags)
1072 {
1073     TRACE("(%p %x)\n", this, flags);
1074     if(flags & 2) {
1075         /* we have an array, with the number of elements stored before the first object */
1076         INT_PTR i, *ptr = (INT_PTR *)this-1;
1077
1078         for(i=*ptr-1; i>=0; i--)
1079             ctype_base_dtor(this+i);
1080         MSVCRT_operator_delete(ptr);
1081     } else {
1082         ctype_base_dtor(this);
1083         if(flags & 1)
1084             MSVCRT_operator_delete(this);
1085     }
1086
1087     return this;
1088 }
1089
1090 /* ?id@?$ctype@D@std@@2V0locale@2@A */
1091 locale_id ctype_char_id = {0};
1092 /* ?table_size@?$ctype@D@std@@2IB */
1093 /* ?table_size@?$ctype@D@std@@2_KB */
1094 MSVCP_size_t ctype_char_table_size = 256;
1095
1096 /* ??_7?$ctype@D@std@@6B@ */
1097 extern const vtable_ptr MSVCP_ctype_char_vtable;
1098
1099 /* ?_Init@?$ctype@D@std@@IAEXABV_Locinfo@2@@Z */
1100 /* ?_Init@?$ctype@D@std@@IEAAXAEBV_Locinfo@2@@Z */
1101 DEFINE_THISCALL_WRAPPER(ctype_char__Init, 8)
1102 void __thiscall ctype_char__Init(ctype_char *this, const _Locinfo *locinfo)
1103 {
1104     TRACE("(%p %p)\n", this, locinfo);
1105     _Locinfo__Getctype(locinfo, &this->ctype);
1106 }
1107
1108 /* ?_Tidy@?$ctype@D@std@@IAEXXZ */
1109 /* ?_Tidy@?$ctype@D@std@@IEAAXXZ */
1110 static void ctype_char__Tidy(ctype_char *this)
1111 {
1112     TRACE("(%p)\n", this);
1113
1114     if(this->ctype.delfl)
1115         free((short*)this->ctype.table);
1116 }
1117
1118 /* ?classic_table@?$ctype@D@std@@KAPBFXZ */
1119 /* ?classic_table@?$ctype@D@std@@KAPEBFXZ */
1120 const short* __cdecl ctype_char_classic_table(void)
1121 {
1122     TRACE("()\n");
1123     return &((short*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_ctype"))[1];
1124 }
1125
1126 /* ??0?$ctype@D@std@@QAE@ABV_Locinfo@1@I@Z */
1127 /* ??0?$ctype@D@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1128 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_locinfo, 12)
1129 ctype_char* __thiscall ctype_char_ctor_locinfo(ctype_char *this,
1130         const _Locinfo *locinfo, MSVCP_size_t refs)
1131 {
1132     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1133     ctype_base_ctor_refs(&this->base, refs);
1134     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1135     ctype_char__Init(this, locinfo);
1136     return this;
1137 }
1138
1139 /* ??0?$ctype@D@std@@QAE@PBF_NI@Z */
1140 /* ??0?$ctype@D@std@@QEAA@PEBF_N_K@Z */
1141 DEFINE_THISCALL_WRAPPER(ctype_char_ctor_table, 16)
1142 ctype_char* __thiscall ctype_char_ctor_table(ctype_char *this,
1143         const short *table, MSVCP_bool delete, MSVCP_size_t refs)
1144 {
1145     _Locinfo locinfo;
1146
1147     TRACE("(%p %p %d %lu)\n", this, table, delete, refs);
1148
1149     ctype_base_ctor_refs(&this->base, refs);
1150     this->base.facet.vtable = &MSVCP_ctype_char_vtable;
1151
1152     _Locinfo_ctor(&locinfo);
1153     ctype_char__Init(this, &locinfo);
1154     _Locinfo_dtor(&locinfo);
1155
1156     if(table) {
1157         ctype_char__Tidy(this);
1158         this->ctype.table = table;
1159         this->ctype.delfl = delete;
1160     }
1161     return this;
1162 }
1163
1164 /* ??_F?$ctype@D@std@@QAEXXZ */
1165 /* ??_F?$ctype@D@std@@QEAAXXZ */
1166 DEFINE_THISCALL_WRAPPER(ctype_char_ctor, 4)
1167 ctype_char* __thiscall ctype_char_ctor(ctype_char *this)
1168 {
1169     return ctype_char_ctor_table(this, NULL, FALSE, 0);
1170 }
1171
1172 /* ??1?$ctype@D@std@@MAE@XZ */
1173 /* ??1?$ctype@D@std@@MEAA@XZ */
1174 static void ctype_char_dtor(ctype_char *this)
1175 {
1176     TRACE("(%p)\n", this);
1177     ctype_char__Tidy(this);
1178 }
1179
1180 DEFINE_THISCALL_WRAPPER(ctype_char_vector_dtor, 8)
1181 ctype_char* __thiscall ctype_char_vector_dtor(ctype_char *this, unsigned int flags)
1182 {
1183     TRACE("(%p %x)\n", this, flags);
1184     if(flags & 2) {
1185         /* we have an array, with the number of elements stored before the first object */
1186         INT_PTR i, *ptr = (INT_PTR *)this-1;
1187
1188         for(i=*ptr-1; i>=0; i--)
1189             ctype_char_dtor(this+i);
1190         MSVCRT_operator_delete(ptr);
1191     } else {
1192         ctype_char_dtor(this);
1193         if(flags & 1)
1194             MSVCRT_operator_delete(this);
1195     }
1196
1197     return this;
1198 }
1199
1200 /* ?do_narrow@?$ctype@D@std@@MBEDDD@Z */
1201 /* ?do_narrow@?$ctype@D@std@@MEBADDD@Z */
1202 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow_ch, 12)
1203 #define call_ctype_char_do_narrow_ch(this, ch, unused) CALL_VTBL_FUNC(this, 32, \
1204         char, (const ctype_char*, char, char), (this, ch, unused))
1205 char __thiscall ctype_char_do_narrow_ch(const ctype_char *this, char ch, char unused)
1206 {
1207     TRACE("(%p %c %c)\n", this, ch, unused);
1208     return ch;
1209 }
1210
1211 /* ?do_narrow@?$ctype@D@std@@MBEPBDPBD0DPAD@Z */
1212 /* ?do_narrow@?$ctype@D@std@@MEBAPEBDPEBD0DPEAD@Z */
1213 DEFINE_THISCALL_WRAPPER(ctype_char_do_narrow, 20)
1214 #define call_ctype_char_do_narrow(this, first, last, unused, dest) CALL_VTBL_FUNC(this, 28, \
1215         const char*, (const ctype_char*, const char*, const char*, char, char*), \
1216         (this, first, last, unused, dest))
1217 const char* __thiscall ctype_char_do_narrow(const ctype_char *this,
1218         const char *first, const char *last, char unused, char *dest)
1219 {
1220     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1221     memcpy(dest, first, last-first);
1222     return last;
1223 }
1224
1225 /* ?narrow@?$ctype@D@std@@QBEDDD@Z */
1226 /* ?narrow@?$ctype@D@std@@QEBADDD@Z */
1227 DEFINE_THISCALL_WRAPPER(ctype_char_narrow_ch, 12)
1228 char __thiscall ctype_char_narrow_ch(const ctype_char *this, char ch, char dflt)
1229 {
1230     TRACE("(%p %c %c)\n", this, ch, dflt);
1231     return call_ctype_char_do_narrow_ch(this, ch, dflt);
1232 }
1233
1234 /* ?narrow@?$ctype@D@std@@QBEPBDPBD0DPAD@Z */
1235 /* ?narrow@?$ctype@D@std@@QEBAPEBDPEBD0DPEAD@Z */
1236 DEFINE_THISCALL_WRAPPER(ctype_char_narrow, 20)
1237 const char* __thiscall ctype_char_narrow(const ctype_char *this,
1238         const char *first, const char *last, char dflt, char *dest)
1239 {
1240     TRACE("(%p %p %p %c %p)\n", this, first, last, dflt, dest);
1241     return call_ctype_char_do_narrow(this, first, last, dflt, dest);
1242 }
1243
1244 /* ?do_widen@?$ctype@D@std@@MBEDD@Z */
1245 /* ?do_widen@?$ctype@D@std@@MEBADD@Z */
1246 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen_ch, 8)
1247 #define call_ctype_char_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
1248         char, (const ctype_char*, char), (this, ch))
1249 char __thiscall ctype_char_do_widen_ch(const ctype_char *this, char ch)
1250 {
1251     TRACE("(%p %c)\n", this, ch);
1252     return ch;
1253 }
1254
1255 /* ?do_widen@?$ctype@D@std@@MBEPBDPBD0PAD@Z */
1256 /* ?do_widen@?$ctype@D@std@@MEBAPEBDPEBD0PEAD@Z */
1257 DEFINE_THISCALL_WRAPPER(ctype_char_do_widen, 16)
1258 #define call_ctype_char_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 20, \
1259         const char*, (const ctype_char*, const char*, const char*, char*), \
1260         (this, first, last, dest))
1261 const char* __thiscall ctype_char_do_widen(const ctype_char *this,
1262         const char *first, const char *last, char *dest)
1263 {
1264     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1265     memcpy(dest, first, last-first);
1266     return last;
1267 }
1268
1269 /* ?widen@?$ctype@D@std@@QBEDD@Z */
1270 /* ?widen@?$ctype@D@std@@QEBADD@Z */
1271 DEFINE_THISCALL_WRAPPER(ctype_char_widen_ch, 8)
1272 char __thiscall ctype_char_widen_ch(const ctype_char *this, char ch)
1273 {
1274     TRACE("(%p %c)\n", this, ch);
1275     return call_ctype_char_do_widen_ch(this, ch);
1276 }
1277
1278 /* ?widen@?$ctype@D@std@@QBEPBDPBD0PAD@Z */
1279 /* ?widen@?$ctype@D@std@@QEBAPEBDPEBD0PEAD@Z */
1280 DEFINE_THISCALL_WRAPPER(ctype_char_widen, 16)
1281 const char* __thiscall ctype_char_widen(const ctype_char *this,
1282         const char *first, const char *last, char *dest)
1283 {
1284     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1285     return call_ctype_char_do_widen(this, first, last, dest);
1286 }
1287
1288 /* ?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1289 /* ?_Getcat@?$ctype@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1290 static MSVCP_size_t ctype_char__Getcat(const locale_facet **facet, const locale *loc)
1291 {
1292     TRACE("(%p %p)\n", facet, loc);
1293
1294     if(facet && !*facet) {
1295         _Locinfo locinfo;
1296
1297         *facet = MSVCRT_operator_new(sizeof(ctype_char));
1298         if(!*facet) {
1299             ERR("Out of memory\n");
1300             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1301             return 0;
1302         }
1303
1304         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
1305         ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
1306         _Locinfo_dtor(&locinfo);
1307     }
1308
1309     return LC_CTYPE;
1310 }
1311
1312 ctype_char* ctype_char_use_facet(const locale *loc)
1313 {
1314     static ctype_char *obj = NULL;
1315
1316     _Lockit lock;
1317     const locale_facet *fac;
1318
1319     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1320     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_char_id));
1321     if(fac) {
1322         _Lockit_dtor(&lock);
1323         return (ctype_char*)fac;
1324     }
1325
1326     if(obj) {
1327         _Lockit_dtor(&lock);
1328         return obj;
1329     }
1330
1331     ctype_char__Getcat(&fac, loc);
1332     obj = (ctype_char*)fac;
1333     locale_facet__Incref(&obj->base.facet);
1334     locale_facet_register(&obj->base.facet);
1335     _Lockit_dtor(&lock);
1336
1337     return obj;
1338 }
1339
1340 /* _Tolower */
1341 int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
1342 {
1343     unsigned int cp;
1344
1345     TRACE("%d %p\n", ch, ctype);
1346
1347     if(ctype)
1348         cp = ctype->page;
1349     else
1350         cp = ___lc_codepage_func();
1351
1352     /* Don't convert to unicode in case of C locale */
1353     if(!cp) {
1354         if(ch>='A' && ch<='Z')
1355             ch = ch-'A'+'a';
1356         return ch;
1357     } else {
1358         WCHAR wide, lower;
1359         char str[2];
1360         int size;
1361
1362         if(ch > 255) {
1363             str[0] = (ch>>8) & 255;
1364             str[1] = ch & 255;
1365             size = 2;
1366         } else {
1367             str[0] = ch & 255;
1368             size = 1;
1369         }
1370
1371         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1372             return ch;
1373
1374         lower = tolowerW(wide);
1375         if(lower == wide)
1376             return ch;
1377
1378         WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
1379
1380         return str[0] + (str[1]<<8);
1381     }
1382 }
1383
1384 /* ?do_tolower@?$ctype@D@std@@MBEDD@Z */
1385 /* ?do_tolower@?$ctype@D@std@@MEBADD@Z */
1386 #define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
1387         char, (const ctype_char*, char), (this, ch))
1388 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
1389 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
1390 {
1391     TRACE("(%p %c)\n", this, ch);
1392     return _Tolower(ch, &this->ctype);
1393 }
1394
1395 /* ?do_tolower@?$ctype@D@std@@MBEPBDPADPBD@Z */
1396 /* ?do_tolower@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1397 #define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
1398         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1399 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
1400 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
1401 {
1402     TRACE("(%p %p %p)\n", this, first, last);
1403     for(; first<last; first++)
1404         *first = _Tolower(*first, &this->ctype);
1405     return last;
1406 }
1407
1408 /* ?tolower@?$ctype@D@std@@QBEDD@Z */
1409 /* ?tolower@?$ctype@D@std@@QEBADD@Z */
1410 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
1411 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
1412 {
1413     TRACE("(%p %c)\n", this, ch);
1414     return call_ctype_char_do_tolower_ch(this, ch);
1415 }
1416
1417 /* ?tolower@?$ctype@D@std@@QBEPBDPADPBD@Z */
1418 /* ?tolower@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1419 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
1420 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
1421 {
1422     TRACE("(%p %p %p)\n", this, first, last);
1423     return call_ctype_char_do_tolower(this, first, last);
1424 }
1425
1426 /* _Toupper */
1427 int __cdecl _Toupper(int ch, const _Ctypevec *ctype)
1428 {
1429     unsigned int cp;
1430
1431     TRACE("%d %p\n", ch, ctype);
1432
1433     if(ctype)
1434         cp = ctype->page;
1435     else
1436         cp = ___lc_codepage_func();
1437
1438     /* Don't convert to unicode in case of C locale */
1439     if(!cp) {
1440         if(ch>='a' && ch<='z')
1441             ch = ch-'a'+'A';
1442         return ch;
1443     } else {
1444         WCHAR wide, upper;
1445         char str[2];
1446         int size;
1447
1448         if(ch > 255) {
1449             str[0] = (ch>>8) & 255;
1450             str[1] = ch & 255;
1451             size = 2;
1452         } else {
1453             str[0] = ch & 255;
1454             size = 1;
1455         }
1456
1457         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
1458             return ch;
1459
1460         upper = toupperW(wide);
1461         if(upper == wide)
1462             return ch;
1463
1464         WideCharToMultiByte(cp, 0, &upper, 1, str, 2, NULL, NULL);
1465
1466         return str[0] + (str[1]<<8);
1467     }
1468 }
1469
1470 /* ?do_toupper@?$ctype@D@std@@MBEDD@Z */
1471 /* ?do_toupper@?$ctype@D@std@@MEBADD@Z */
1472 #define call_ctype_char_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 16, \
1473         char, (const ctype_char*, char), (this, ch))
1474 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper_ch, 8)
1475 char __thiscall ctype_char_do_toupper_ch(const ctype_char *this, char ch)
1476 {
1477     TRACE("(%p %c)\n", this, ch);
1478     return _Toupper(ch, &this->ctype);
1479 }
1480
1481 /* ?do_toupper@?$ctype@D@std@@MBEPBDPADPBD@Z */
1482 /* ?do_toupper@?$ctype@D@std@@MEBAPEBDPEADPEBD@Z */
1483 #define call_ctype_char_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 12, \
1484         const char*, (const ctype_char*, char*, const char*), (this, first, last))
1485 DEFINE_THISCALL_WRAPPER(ctype_char_do_toupper, 12)
1486 const char* __thiscall ctype_char_do_toupper(const ctype_char *this,
1487         char *first, const char *last)
1488 {
1489     TRACE("(%p %p %p)\n", this, first, last);
1490     for(; first<last; first++)
1491         *first = _Toupper(*first, &this->ctype);
1492     return last;
1493 }
1494
1495 /* ?toupper@?$ctype@D@std@@QBEDD@Z */
1496 /* ?toupper@?$ctype@D@std@@QEBADD@Z */
1497 DEFINE_THISCALL_WRAPPER(ctype_char_toupper_ch, 8)
1498 char __thiscall ctype_char_toupper_ch(const ctype_char *this, char ch)
1499 {
1500     TRACE("(%p %c)\n", this, ch);
1501     return call_ctype_char_do_toupper_ch(this, ch);
1502 }
1503
1504 /* ?toupper@?$ctype@D@std@@QBEPBDPADPBD@Z */
1505 /* ?toupper@?$ctype@D@std@@QEBAPEBDPEADPEBD@Z */
1506 DEFINE_THISCALL_WRAPPER(ctype_char_toupper, 12)
1507 const char* __thiscall ctype_char_toupper(const ctype_char *this, char *first, const char *last)
1508 {
1509     TRACE("(%p %p %p)\n", this, first, last);
1510     return call_ctype_char_do_toupper(this, first, last);
1511 }
1512
1513 /* ?is@?$ctype@D@std@@QBE_NFD@Z */
1514 /* ?is@?$ctype@D@std@@QEBA_NFD@Z */
1515 DEFINE_THISCALL_WRAPPER(ctype_char_is_ch, 12)
1516 MSVCP_bool __thiscall ctype_char_is_ch(const ctype_char *this, short mask, char ch)
1517 {
1518     TRACE("(%p %x %c)\n", this, mask, ch);
1519     return (this->ctype.table[(unsigned char)ch] & mask) != 0;
1520 }
1521
1522 /* ?is@?$ctype@D@std@@QBEPBDPBD0PAF@Z */
1523 /* ?is@?$ctype@D@std@@QEBAPEBDPEBD0PEAF@Z */
1524 DEFINE_THISCALL_WRAPPER(ctype_char_is, 16)
1525 const char* __thiscall ctype_char_is(const ctype_char *this, const char *first, const char *last, short *dest)
1526 {
1527     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1528     for(; first<last; first++)
1529         *dest++ = this->ctype.table[(unsigned char)*first];
1530     return last;
1531 }
1532
1533 /* ?scan_is@?$ctype@D@std@@QBEPBDFPBD0@Z */
1534 /* ?scan_is@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1535 DEFINE_THISCALL_WRAPPER(ctype_char_scan_is, 16)
1536 const char* __thiscall ctype_char_scan_is(const ctype_char *this, short mask, const char *first, const char *last)
1537 {
1538     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1539     for(; first<last; first++)
1540         if(!ctype_char_is_ch(this, mask, *first))
1541             break;
1542     return first;
1543 }
1544
1545 /* ?scan_not@?$ctype@D@std@@QBEPBDFPBD0@Z */
1546 /* ?scan_not@?$ctype@D@std@@QEBAPEBDFPEBD0@Z */
1547 DEFINE_THISCALL_WRAPPER(ctype_char_scan_not, 16)
1548 const char* __thiscall ctype_char_scan_not(const ctype_char *this, short mask, const char *first, const char *last)
1549 {
1550     TRACE("(%p %x %p %p)\n", this, mask, first, last);
1551     for(; first<last; first++)
1552         if(ctype_char_is_ch(this, mask, *first))
1553             break;
1554     return first;
1555 }
1556
1557 /* ?table@?$ctype@D@std@@IBEPBFXZ */
1558 /* ?table@?$ctype@D@std@@IEBAPEBFXZ */
1559 DEFINE_THISCALL_WRAPPER(ctype_char_table, 4)
1560 const short* __thiscall ctype_char_table(const ctype_char *this)
1561 {
1562     TRACE("(%p)\n", this);
1563     return this->ctype.table;
1564 }
1565
1566 /* ?id@?$ctype@_W@std@@2V0locale@2@A */
1567 static locale_id ctype_wchar_id = {0};
1568 /* ?id@?$ctype@G@std@@2V0locale@2@A */
1569 locale_id ctype_short_id = {0};
1570
1571 /* ??_7?$ctype@_W@std@@6B@ */
1572 extern const vtable_ptr MSVCP_ctype_wchar_vtable;
1573 /* ??_7?$ctype@G@std@@6B@ */
1574 extern const vtable_ptr MSVCP_ctype_short_vtable;
1575
1576 /* ?_Init@?$ctype@_W@std@@IAEXABV_Locinfo@2@@Z */
1577 /* ?_Init@?$ctype@_W@std@@IEAAXAEBV_Locinfo@2@@Z */
1578 /* ?_Init@?$ctype@G@std@@IAEXABV_Locinfo@2@@Z */
1579 /* ?_Init@?$ctype@G@std@@IEAAXAEBV_Locinfo@2@@Z */
1580 DEFINE_THISCALL_WRAPPER(ctype_wchar__Init, 8)
1581 void __thiscall ctype_wchar__Init(ctype_wchar *this, const _Locinfo *locinfo)
1582 {
1583     TRACE("(%p %p)\n", this, locinfo);
1584     _Locinfo__Getctype(locinfo, &this->ctype);
1585     _Locinfo__Getcvt(locinfo, &this->cvt);
1586 }
1587
1588 /* ??0?$ctype@_W@std@@QAE@ABV_Locinfo@1@I@Z */
1589 /* ??0?$ctype@_W@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1590 static ctype_wchar* ctype_wchar_ctor_locinfo(ctype_wchar *this,
1591         const _Locinfo *locinfo, MSVCP_size_t refs)
1592 {
1593     TRACE("(%p %p %lu)\n", this, locinfo, refs);
1594     ctype_base_ctor_refs(&this->base, refs);
1595     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1596     ctype_wchar__Init(this, locinfo);
1597     return this;
1598 }
1599
1600 /* ??0?$ctype@G@std@@QAE@ABV_Locinfo@1@I@Z */
1601 /* ??0?$ctype@G@std@@QEAA@AEBV_Locinfo@1@_K@Z */
1602 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_locinfo, 12)
1603 ctype_wchar* __thiscall ctype_short_ctor_locinfo(ctype_wchar *this,
1604         const _Locinfo *locinfo, MSVCP_size_t refs)
1605 {
1606     ctype_wchar *ret = ctype_wchar_ctor_locinfo(this, locinfo, refs);
1607     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1608     return ret;
1609 }
1610
1611 /* ??0?$ctype@_W@std@@QAE@I@Z */
1612 /* ??0?$ctype@_W@std@@QEAA@_K@Z */
1613 static ctype_wchar* ctype_wchar_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1614 {
1615     _Locinfo locinfo;
1616
1617     TRACE("(%p %lu)\n", this, refs);
1618
1619     ctype_base_ctor_refs(&this->base, refs);
1620     this->base.facet.vtable = &MSVCP_ctype_wchar_vtable;
1621
1622     _Locinfo_ctor(&locinfo);
1623     ctype_wchar__Init(this, &locinfo);
1624     _Locinfo_dtor(&locinfo);
1625     return this;
1626 }
1627
1628 /* ??0?$ctype@G@std@@QAE@I@Z */
1629 /* ??0?$ctype@G@std@@QEAA@_K@Z */
1630 DEFINE_THISCALL_WRAPPER(ctype_short_ctor_refs, 8)
1631 ctype_wchar* __thiscall ctype_short_ctor_refs(ctype_wchar *this, MSVCP_size_t refs)
1632 {
1633     ctype_wchar *ret = ctype_wchar_ctor_refs(this, refs);
1634     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1635     return ret;
1636 }
1637
1638 /* ??_F?$ctype@_W@std@@QAEXXZ */
1639 /* ??_F?$ctype@_W@std@@QEAAXXZ */
1640 static ctype_wchar* ctype_wchar_ctor(ctype_wchar *this)
1641 {
1642     TRACE("(%p)\n", this);
1643     return ctype_short_ctor_refs(this, 0);
1644 }
1645
1646 /* ??_F?$ctype@G@std@@QAEXXZ */
1647 /* ??_F?$ctype@G@std@@QEAAXXZ */
1648 DEFINE_THISCALL_WRAPPER(ctype_short_ctor, 4)
1649 ctype_wchar* __thiscall ctype_short_ctor(ctype_wchar *this)
1650 {
1651     ctype_wchar *ret = ctype_wchar_ctor(this);
1652     this->base.facet.vtable = &MSVCP_ctype_short_vtable;
1653     return ret;
1654 }
1655
1656 /* ??1?$ctype@_W@std@@MAE@XZ */
1657 /* ??1?$ctype@_W@std@@MEAA@XZ */
1658 /* ??1?$ctype@G@std@@MAE@XZ */
1659 /* ??1?$ctype@G@std@@MEAA@XZ */
1660 static void ctype_wchar_dtor(ctype_wchar *this)
1661 {
1662     TRACE("(%p)\n", this);
1663     if(this->ctype.delfl)
1664         free((void*)this->ctype.table);
1665 }
1666
1667 DEFINE_THISCALL_WRAPPER(ctype_wchar_vector_dtor, 8)
1668 ctype_wchar* __thiscall ctype_wchar_vector_dtor(ctype_wchar *this, unsigned int flags)
1669 {
1670     TRACE("(%p %x)\n", this, flags);
1671     if(flags & 2) {
1672         /* we have an array, with the number of elements stored before the first object */
1673         INT_PTR i, *ptr = (INT_PTR *)this-1;
1674
1675         for(i=*ptr-1; i>=0; i--)
1676             ctype_wchar_dtor(this+i);
1677         MSVCRT_operator_delete(ptr);
1678     } else {
1679         ctype_wchar_dtor(this);
1680         if(flags & 1)
1681             MSVCRT_operator_delete(this);
1682     }
1683
1684     return this;
1685 }
1686
1687 /* _Wcrtomb */
1688 int __cdecl _Wcrtomb(char *s, wchar_t wch, int *state, const _Cvtvec *cvt)
1689 {
1690     int cp, size;
1691     BOOL def;
1692
1693     TRACE("%p %d %p %p\n", s, wch, state, cvt);
1694
1695     if(cvt)
1696         cp = cvt->page;
1697     else
1698         cp = ___lc_codepage_func();
1699
1700     if(!cp) {
1701         if(wch > 255) {
1702            *_errno() = EILSEQ;
1703            return -1;
1704         }
1705
1706         *s = wch & 255;
1707         return 1;
1708     }
1709
1710     size = WideCharToMultiByte(cp, 0, &wch, 1, s, MB_LEN_MAX, NULL, &def);
1711     if(!size || def) {
1712         *_errno() = EILSEQ;
1713         return -1;
1714     }
1715
1716     return size;
1717 }
1718
1719 /* ?_Donarrow@?$ctype@_W@std@@IBED_WD@Z */
1720 /* ?_Donarrow@?$ctype@_W@std@@IEBAD_WD@Z */
1721 /* ?_Donarrow@?$ctype@G@std@@IBEDGD@Z */
1722 /* ?_Donarrow@?$ctype@G@std@@IEBADGD@Z */
1723 static char ctype_wchar__Donarrow(const ctype_wchar *this, wchar_t ch, char dflt)
1724 {
1725     char buf[MB_LEN_MAX];
1726
1727     TRACE("(%p %d %d)\n", this, ch, dflt);
1728
1729     return _Wcrtomb(buf, ch, NULL, &this->cvt)==1 ? buf[0] : dflt;
1730 }
1731
1732 /* ?do_narrow@?$ctype@_W@std@@MBED_WD@Z */
1733 /* ?do_narrow@?$ctype@_W@std@@MEBAD_WD@Z */
1734 /* ?do_narrow@?$ctype@G@std@@MBEDGD@Z */
1735 /* ?do_narrow@?$ctype@G@std@@MEBADGD@Z */
1736 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow_ch, 12)
1737 #define call_ctype_wchar_do_narrow_ch(this, ch, dflt) CALL_VTBL_FUNC(this, 48, \
1738         char, (const ctype_wchar*, wchar_t, char), (this, ch, dflt))
1739 char __thiscall ctype_wchar_do_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1740 {
1741     return ctype_wchar__Donarrow(this, ch, dflt);
1742 }
1743
1744 /* ?do_narrow@?$ctype@_W@std@@MBEPB_WPB_W0DPAD@Z */
1745 /* ?do_narrow@?$ctype@_W@std@@MEBAPEB_WPEB_W0DPEAD@Z */
1746 /* ?do_narrow@?$ctype@G@std@@MBEPBGPBG0DPAD@Z */
1747 /* ?do_narrow@?$ctype@G@std@@MEBAPEBGPEBG0DPEAD@Z */
1748 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_narrow, 20)
1749 #define call_ctype_wchar_do_narrow(this, first, last, dflt, dest) CALL_VTBL_FUNC(this, 44, \
1750         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, char, char*), \
1751         (this, first, last, dflt, dest))
1752 const wchar_t* __thiscall ctype_wchar_do_narrow(const ctype_wchar *this,
1753         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
1754 {
1755     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
1756     for(; first<last; first++)
1757         *dest++ = ctype_wchar__Donarrow(this, *first, dflt);
1758     return last;
1759 }
1760
1761 /* ?narrow@?$ctype@_W@std@@QBED_WD@Z */
1762 /* ?narrow@?$ctype@_W@std@@QEBAD_WD@Z */
1763 /* ?narrow@?$ctype@G@std@@QBEDGD@Z */
1764 /* ?narrow@?$ctype@G@std@@QEBADGD@Z */
1765 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow_ch, 12)
1766 char __thiscall ctype_wchar_narrow_ch(const ctype_wchar *this, wchar_t ch, char dflt)
1767 {
1768     TRACE("(%p %d %d)\n", this, ch, dflt);
1769     return call_ctype_wchar_do_narrow_ch(this, ch, dflt);
1770 }
1771
1772 /* ?narrow@?$ctype@_W@std@@QBEPB_WPB_W0DPAD@Z */
1773 /* ?narrow@?$ctype@_W@std@@QEBAPEB_WPEB_W0DPEAD@Z */
1774 /* ?narrow@?$ctype@G@std@@QBEPBGPBG0DPAD@Z */
1775 /* ?narrow@?$ctype@G@std@@QEBAPEBGPEBG0DPEAD@Z */
1776 DEFINE_THISCALL_WRAPPER(ctype_wchar_narrow, 20)
1777 const wchar_t* __thiscall ctype_wchar_narrow(const ctype_wchar *this,
1778         const wchar_t *first, const wchar_t *last, char dflt, char *dest)
1779 {
1780     TRACE("(%p %p %p %d %p)\n", this, first, last, dflt, dest);
1781     return call_ctype_wchar_do_narrow(this, first, last, dflt, dest);
1782 }
1783
1784 /* _Mbrtowc */
1785 int __cdecl _Mbrtowc(wchar_t *out, const char *in, MSVCP_size_t len, int *state, const _Cvtvec *cvt)
1786 {
1787     int i, cp;
1788     CPINFO cp_info;
1789     BOOL is_lead;
1790
1791     TRACE("(%p %p %lu %p %p)\n", out, in, len, state, cvt);
1792
1793     if(!len)
1794         return 0;
1795
1796     if(cvt)
1797         cp = cvt->page;
1798     else
1799         cp = ___lc_codepage_func();
1800
1801     if(!cp) {
1802         if(out)
1803             *out = (unsigned char)*in;
1804
1805         *state = 0;
1806         return *in ? 1 : 0;
1807     }
1808
1809     if(*state) {
1810         ((char*)state)[1] = *in;
1811
1812         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, (char*)state, 2, out, out ? 1 : 0)) {
1813             *state = 0;
1814             *_errno() = EILSEQ;
1815             return -1;
1816         }
1817
1818         *state = 0;
1819         return 2;
1820     }
1821
1822     GetCPInfo(cp, &cp_info);
1823     is_lead = FALSE;
1824     for(i=0; i<MAX_LEADBYTES; i+=2) {
1825         if(!cp_info.LeadByte[i+1])
1826             break;
1827         if((unsigned char)*in>=cp_info.LeadByte[i] && (unsigned char)*in<=cp_info.LeadByte[i+1]) {
1828             is_lead = TRUE;
1829             break;
1830         }
1831     }
1832
1833     if(is_lead) {
1834         if(len == 1) {
1835             *state = (unsigned char)*in;
1836             return -2;
1837         }
1838
1839         if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 2, out, out ? 1 : 0)) {
1840             *_errno() = EILSEQ;
1841             return -1;
1842         }
1843         return 2;
1844     }
1845
1846     if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, in, 1, out, out ? 1 : 0)) {
1847         *_errno() = EILSEQ;
1848         return -1;
1849     }
1850     return 1;
1851 }
1852
1853 /* ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z */
1854 /* ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z */
1855 /* ?_Dowiden@?$ctype@G@std@@IBEGD@Z */
1856 /* ?_Dowiden@?$ctype@G@std@@IEBAGD@Z */
1857 static wchar_t ctype_wchar__Dowiden(const ctype_wchar *this, char ch)
1858 {
1859     wchar_t ret;
1860     int state = 0;
1861     TRACE("(%p %d)\n", this, ch);
1862     return _Mbrtowc(&ret, &ch, 1, &state, &this->cvt)<0 ? WEOF : ret;
1863 }
1864
1865 /* ?do_widen@?$ctype@_W@std@@MBE_WD@Z */
1866 /* ?do_widen@?$ctype@_W@std@@MEBA_WD@Z */
1867 /* ?do_widen@?$ctype@G@std@@MBEGD@Z */
1868 /* ?do_widen@?$ctype@G@std@@MEBAGD@Z */
1869 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen_ch, 8)
1870 #define call_ctype_wchar_do_widen_ch(this, ch) CALL_VTBL_FUNC(this, 40, \
1871         wchar_t, (const ctype_wchar*, char), (this, ch))
1872 wchar_t __thiscall ctype_wchar_do_widen_ch(const ctype_wchar *this, char ch)
1873 {
1874     return ctype_wchar__Dowiden(this, ch);
1875 }
1876
1877 /* ?do_widen@?$ctype@_W@std@@MBEPBDPBD0PA_W@Z */
1878 /* ?do_widen@?$ctype@_W@std@@MEBAPEBDPEBD0PEA_W@Z */
1879 /* ?do_widen@?$ctype@G@std@@MBEPBDPBD0PAG@Z */
1880 /* ?do_widen@?$ctype@G@std@@MEBAPEBDPEBD0PEAG@Z */
1881 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_widen, 16)
1882 #define call_ctype_wchar_do_widen(this, first, last, dest) CALL_VTBL_FUNC(this, 36, \
1883         const char*, (const ctype_wchar*, const char*, const char*, wchar_t*), \
1884         (this, first, last, dest))
1885 const char* __thiscall ctype_wchar_do_widen(const ctype_wchar *this,
1886         const char *first, const char *last, wchar_t *dest)
1887 {
1888     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1889     for(; first<last; first++)
1890         *dest++ = ctype_wchar__Dowiden(this, *first);
1891     return last;
1892 }
1893
1894 /* ?widen@?$ctype@_W@std@@QBE_WD@Z */
1895 /* ?widen@?$ctype@_W@std@@QEBA_WD@Z */
1896 /* ?widen@?$ctype@G@std@@QBEGD@Z */
1897 /* ?widen@?$ctype@G@std@@QEBAGD@Z */
1898 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen_ch, 8)
1899 wchar_t __thiscall ctype_wchar_widen_ch(const ctype_wchar *this, char ch)
1900 {
1901     TRACE("(%p %d)\n", this, ch);
1902     return call_ctype_wchar_do_widen_ch(this, ch);
1903 }
1904
1905 /* ?widen@?$ctype@_W@std@@QBEPBDPBD0PA_W@Z */
1906 /* ?widen@?$ctype@_W@std@@QEBAPEBDPEBD0PEA_W@Z */
1907 /* ?widen@?$ctype@G@std@@QBEPBDPBD0PAG@Z */
1908 /* ?widen@?$ctype@G@std@@QEBAPEBDPEBD0PEAG@Z */
1909 DEFINE_THISCALL_WRAPPER(ctype_wchar_widen, 16)
1910 const char* __thiscall ctype_wchar_widen(const ctype_wchar *this,
1911         const char *first, const char *last, wchar_t *dest)
1912 {
1913     TRACE("(%p %p %p %p)\n", this, first, last, dest);
1914     return call_ctype_wchar_do_widen(this, first, last, dest);
1915 }
1916
1917 /* ?_Getcat@?$ctype@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1918 /* ?_Getcat@?$ctype@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1919 static MSVCP_size_t ctype_wchar__Getcat(const locale_facet **facet, const locale *loc)
1920 {
1921     TRACE("(%p %p)\n", facet, loc);
1922
1923     if(facet && !*facet) {
1924         _Locinfo locinfo;
1925
1926         *facet = MSVCRT_operator_new(sizeof(ctype_wchar));
1927         if(!*facet) {
1928             ERR("Out of memory\n");
1929             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
1930             return 0;
1931         }
1932
1933         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
1934         ctype_wchar_ctor_locinfo((ctype_wchar*)*facet, &locinfo, 0);
1935         _Locinfo_dtor(&locinfo);
1936     }
1937
1938     return LC_CTYPE;
1939 }
1940
1941 /* ?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
1942 /* ?_Getcat@?$ctype@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
1943 static MSVCP_size_t ctype_short__Getcat(const locale_facet **facet, const locale *loc)
1944 {
1945     if(facet && !*facet) {
1946         ctype_wchar__Getcat(facet, loc);
1947         (*(locale_facet**)facet)->vtable = &MSVCP_ctype_short_vtable;
1948     }
1949
1950     return LC_CTYPE;
1951 }
1952
1953 /* _Towlower */
1954 static wchar_t _Towlower(wchar_t ch, const _Ctypevec *ctype)
1955 {
1956     TRACE("(%d %p)\n", ch, ctype);
1957     return tolowerW(ch);
1958 }
1959
1960 ctype_wchar* ctype_wchar_use_facet(const locale *loc)
1961 {
1962     static ctype_wchar *obj = NULL;
1963
1964     _Lockit lock;
1965     const locale_facet *fac;
1966
1967     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1968     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_wchar_id));
1969     if(fac) {
1970         _Lockit_dtor(&lock);
1971         return (ctype_wchar*)fac;
1972     }
1973
1974     if(obj) {
1975         _Lockit_dtor(&lock);
1976         return obj;
1977     }
1978
1979     ctype_wchar__Getcat(&fac, loc);
1980     obj = (ctype_wchar*)fac;
1981     locale_facet__Incref(&obj->base.facet);
1982     locale_facet_register(&obj->base.facet);
1983     _Lockit_dtor(&lock);
1984
1985     return obj;
1986 }
1987
1988 ctype_wchar* ctype_short_use_facet(const locale *loc)
1989 {
1990     static ctype_wchar *obj = NULL;
1991
1992     _Lockit lock;
1993     const locale_facet *fac;
1994
1995     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
1996     fac = locale__Getfacet(loc, locale_id_operator_size_t(&ctype_short_id));
1997     if(fac) {
1998         _Lockit_dtor(&lock);
1999         return (ctype_wchar*)fac;
2000     }
2001
2002     if(obj) {
2003         _Lockit_dtor(&lock);
2004         return obj;
2005     }
2006
2007     ctype_short__Getcat(&fac, loc);
2008     obj = (ctype_wchar*)fac;
2009     locale_facet__Incref(&obj->base.facet);
2010     locale_facet_register(&obj->base.facet);
2011     _Lockit_dtor(&lock);
2012
2013     return obj;
2014 }
2015
2016 /* ?do_tolower@?$ctype@_W@std@@MBE_W_W@Z */
2017 /* ?do_tolower@?$ctype@_W@std@@MEBA_W_W@Z */
2018 /* ?do_tolower@?$ctype@G@std@@MBEGG@Z */
2019 /* ?do_tolower@?$ctype@G@std@@MEBAGG@Z */
2020 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower_ch, 8)
2021 #define call_ctype_wchar_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 24, \
2022         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2023 wchar_t __thiscall ctype_wchar_do_tolower_ch(const ctype_wchar *this, wchar_t ch)
2024 {
2025     return _Towlower(ch, &this->ctype);
2026 }
2027
2028 /* ?do_tolower@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2029 /* ?do_tolower@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2030 /* ?do_tolower@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2031 /* ?do_tolower@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2032 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_tolower, 12)
2033 #define call_ctype_wchar_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 20, \
2034         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2035         (this, first, last))
2036 const wchar_t* __thiscall ctype_wchar_do_tolower(const ctype_wchar *this,
2037         wchar_t *first, const wchar_t *last)
2038 {
2039     TRACE("(%p %p %p)\n", this, first, last);
2040     for(; first<last; first++)
2041         *first = _Towlower(*first, &this->ctype);
2042     return last;
2043 }
2044
2045 /* ?tolower@?$ctype@_W@std@@QBE_W_W@Z */
2046 /* ?tolower@?$ctype@_W@std@@QEBA_W_W@Z */
2047 /* ?tolower@?$ctype@G@std@@QBEGG@Z */
2048 /* ?tolower@?$ctype@G@std@@QEBAGG@Z */
2049 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower_ch, 8)
2050 wchar_t __thiscall ctype_wchar_tolower_ch(const ctype_wchar *this, wchar_t ch)
2051 {
2052     TRACE("(%p %d)\n", this, ch);
2053     return call_ctype_wchar_do_tolower_ch(this, ch);
2054 }
2055
2056 /* ?tolower@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2057 /* ?tolower@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2058 /* ?tolower@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2059 /* ?tolower@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2060 DEFINE_THISCALL_WRAPPER(ctype_wchar_tolower, 12)
2061 const wchar_t* __thiscall ctype_wchar_tolower(const ctype_wchar *this,
2062         wchar_t *first, const wchar_t *last)
2063 {
2064     TRACE("(%p %p %p)\n", this, first, last);
2065     return call_ctype_wchar_do_tolower(this, first, last);
2066 }
2067
2068 /* _Towupper */
2069 static wchar_t _Towupper(wchar_t ch, const _Ctypevec *ctype)
2070 {
2071     TRACE("(%d %p)\n", ch, ctype);
2072     return toupperW(ch);
2073 }
2074
2075 /* ?do_toupper@?$ctype@_W@std@@MBE_W_W@Z */
2076 /* ?do_toupper@?$ctype@_W@std@@MEBA_W_W@Z */
2077 /* ?do_toupper@?$ctype@G@std@@MBEGG@Z */
2078 /* ?do_toupper@?$ctype@G@std@@MEBAGG@Z */
2079 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper_ch, 8)
2080 #define call_ctype_wchar_do_toupper_ch(this, ch) CALL_VTBL_FUNC(this, 32, \
2081         wchar_t, (const ctype_wchar*, wchar_t), (this, ch))
2082 wchar_t __thiscall ctype_wchar_do_toupper_ch(const ctype_wchar *this, wchar_t ch)
2083 {
2084     return _Towupper(ch, &this->ctype);
2085 }
2086
2087 /* ?do_toupper@?$ctype@_W@std@@MBEPB_WPA_WPB_W@Z */
2088 /* ?do_toupper@?$ctype@_W@std@@MEBAPEB_WPEA_WPEB_W@Z */
2089 /* ?do_toupper@?$ctype@G@std@@MBEPBGPAGPBG@Z */
2090 /* ?do_toupper@?$ctype@G@std@@MEBAPEBGPEAGPEBG@Z */
2091 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_toupper, 12)
2092 #define call_ctype_wchar_do_toupper(this, first, last) CALL_VTBL_FUNC(this, 28, \
2093         const wchar_t*, (const ctype_wchar*, wchar_t*, const wchar_t*), \
2094         (this, first, last))
2095 const wchar_t* __thiscall ctype_wchar_do_toupper(const ctype_wchar *this,
2096         wchar_t *first, const wchar_t *last)
2097 {
2098     TRACE("(%p %p %p)\n", this, first, last);
2099     for(; first<last; first++)
2100         *first = _Towupper(*first, &this->ctype);
2101     return last;
2102 }
2103
2104 /* ?toupper@?$ctype@_W@std@@QBE_W_W@Z */
2105 /* ?toupper@?$ctype@_W@std@@QEBA_W_W@Z */
2106 /* ?toupper@?$ctype@G@std@@QBEGG@Z */
2107 /* ?toupper@?$ctype@G@std@@QEBAGG@Z */
2108 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper_ch, 8)
2109 wchar_t __thiscall ctype_wchar_toupper_ch(const ctype_wchar *this, wchar_t ch)
2110 {
2111     TRACE("(%p %d)\n", this, ch);
2112     return call_ctype_wchar_do_toupper_ch(this, ch);
2113 }
2114
2115 /* ?toupper@?$ctype@_W@std@@QBEPB_WPA_WPB_W@Z */
2116 /* ?toupper@?$ctype@_W@std@@QEBAPEB_WPEA_WPEB_W@Z */
2117 /* ?toupper@?$ctype@G@std@@QBEPBGPAGPBG@Z */
2118 /* ?toupper@?$ctype@G@std@@QEBAPEBGPEAGPEBG@Z */
2119 DEFINE_THISCALL_WRAPPER(ctype_wchar_toupper, 12)
2120 const wchar_t* __thiscall ctype_wchar_toupper(const ctype_wchar *this,
2121         wchar_t *first, const wchar_t *last)
2122 {
2123     TRACE("(%p %p %p)\n", this, first, last);
2124     return call_ctype_wchar_do_toupper(this, first, last);
2125 }
2126
2127 /* _Getwctypes */
2128 static const wchar_t* _Getwctypes(const wchar_t *first, const wchar_t *last,
2129         short *mask, const _Ctypevec *ctype)
2130 {
2131     TRACE("(%p %p %p %p)\n", first, last, mask, ctype);
2132     GetStringTypeW(CT_CTYPE1, first, last-first, (WORD*)mask);
2133     return last;
2134 }
2135
2136 /* _Getwctype */
2137 static short _Getwctype(wchar_t ch, const _Ctypevec *ctype)
2138 {
2139     short mask = 0;
2140     _Getwctypes(&ch, &ch+1, &mask, ctype);
2141     return mask;
2142 }
2143
2144 /* ?do_is@?$ctype@_W@std@@MBE_NF_W@Z */
2145 /* ?do_is@?$ctype@_W@std@@MEBA_NF_W@Z */
2146 /* ?do_is@?$ctype@G@std@@MBE_NFG@Z */
2147 /* ?do_is@?$ctype@G@std@@MEBA_NFG@Z */
2148 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is_ch, 12)
2149 #define call_ctype_wchar_do_is_ch(this, mask, ch) CALL_VTBL_FUNC(this, 8, \
2150         MSVCP_bool, (const ctype_wchar*, short, wchar_t), (this, mask, ch))
2151 MSVCP_bool __thiscall ctype_wchar_do_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2152 {
2153     TRACE("(%p %x %d)\n", this, mask, ch);
2154     return (_Getwctype(ch, &this->ctype) & mask) != 0;
2155 }
2156
2157 /* ?do_is@?$ctype@_W@std@@MBEPB_WPB_W0PAF@Z */
2158 /* ?do_is@?$ctype@_W@std@@MEBAPEB_WPEB_W0PEAF@Z */
2159 /* ?do_is@?$ctype@G@std@@MBEPBGPBG0PAF@Z */
2160 /* ?do_is@?$ctype@G@std@@MEBAPEBGPEBG0PEAF@Z */
2161 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_is, 16)
2162 #define call_ctype_wchar_do_is(this, first, last, dest) CALL_VTBL_FUNC(this, 4, \
2163         const wchar_t*, (const ctype_wchar*, const wchar_t*, const wchar_t*, short*), \
2164         (this, first, last, dest))
2165 const wchar_t* __thiscall ctype_wchar_do_is(const ctype_wchar *this,
2166         const wchar_t *first, const wchar_t *last, short *dest)
2167 {
2168     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2169     return _Getwctypes(first, last, dest, &this->ctype);
2170 }
2171
2172 /* ?is@?$ctype@_W@std@@QBE_NF_W@Z */
2173 /* ?is@?$ctype@_W@std@@QEBA_NF_W@Z */
2174 /* ?is@?$ctype@G@std@@QBE_NFG@Z */
2175 /* ?is@?$ctype@G@std@@QEBA_NFG@Z */
2176 DEFINE_THISCALL_WRAPPER(ctype_wchar_is_ch, 12)
2177 MSVCP_bool __thiscall ctype_wchar_is_ch(const ctype_wchar *this, short mask, wchar_t ch)
2178 {
2179     TRACE("(%p %x %d)\n", this, mask, ch);
2180     return call_ctype_wchar_do_is_ch(this, mask, ch);
2181 }
2182
2183 /* ?is@?$ctype@_W@std@@QBEPB_WPB_W0PAF@Z */
2184 /* ?is@?$ctype@_W@std@@QEBAPEB_WPEB_W0PEAF@Z */
2185 /* ?is@?$ctype@G@std@@QBEPBGPBG0PAF@Z */
2186 /* ?is@?$ctype@G@std@@QEBAPEBGPEBG0PEAF@Z */
2187 DEFINE_THISCALL_WRAPPER(ctype_wchar_is, 16)
2188 const wchar_t* __thiscall ctype_wchar_is(const ctype_wchar *this,
2189         const wchar_t *first, const wchar_t *last, short *dest)
2190 {
2191     TRACE("(%p %p %p %p)\n", this, first, last, dest);
2192     return call_ctype_wchar_do_is(this, first, last, dest);
2193 }
2194
2195 /* ?do_scan_is@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2196 /* ?do_scan_is@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2197 /* ?do_scan_is@?$ctype@G@std@@MBEPBGFPBG0@Z */
2198 /* ?do_scan_is@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2199 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_is, 16)
2200 #define call_ctype_wchar_do_scan_is(this, mask, first, last) CALL_VTBL_FUNC(this, 12, \
2201         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2202         (this, mask, first, last))
2203 const wchar_t* __thiscall ctype_wchar_do_scan_is(const ctype_wchar *this,
2204         short mask, const wchar_t *first, const wchar_t *last)
2205 {
2206     TRACE("(%p %d %p %p)\n", this, mask, first, last);
2207     for(; first<last; first++)
2208         if(!ctype_wchar_is_ch(this, mask, *first))
2209             break;
2210     return first;
2211 }
2212
2213 /* ?scan_is@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2214 /* ?scan_is@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2215 /* ?scan_is@?$ctype@G@std@@QBEPBGFPBG0@Z */
2216 /* ?scan_is@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2217 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_is, 16)
2218 const wchar_t* __thiscall ctype_wchar_scan_is(const ctype_wchar *this,
2219         short mask, const wchar_t *first, const wchar_t *last)
2220 {
2221     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2222     return call_ctype_wchar_do_scan_is(this, mask, first, last);
2223 }
2224
2225 /* ?do_scan_not@?$ctype@_W@std@@MBEPB_WFPB_W0@Z */
2226 /* ?do_scan_not@?$ctype@_W@std@@MEBAPEB_WFPEB_W0@Z */
2227 /* ?do_scan_not@?$ctype@G@std@@MBEPBGFPBG0@Z */
2228 /* ?do_scan_not@?$ctype@G@std@@MEBAPEBGFPEBG0@Z */
2229 DEFINE_THISCALL_WRAPPER(ctype_wchar_do_scan_not, 16)
2230 #define call_ctype_wchar_do_scan_not(this, mask, first, last) CALL_VTBL_FUNC(this, 16, \
2231         const wchar_t*, (const ctype_wchar*, short, const wchar_t*, const wchar_t*), \
2232         (this, mask, first, last))
2233 const wchar_t* __thiscall ctype_wchar_do_scan_not(const ctype_wchar *this,
2234         short mask, const wchar_t *first, const wchar_t *last)
2235 {
2236     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2237     for(; first<last; first++)
2238         if(ctype_wchar_is_ch(this, mask, *first))
2239             break;
2240     return first;
2241 }
2242
2243 /* ?scan_not@?$ctype@_W@std@@QBEPB_WFPB_W0@Z */
2244 /* ?scan_not@?$ctype@_W@std@@QEBAPEB_WFPEB_W0@Z */
2245 /* ?scan_not@?$ctype@G@std@@QBEPBGFPBG0@Z */
2246 /* ?scan_not@?$ctype@G@std@@QEBAPEBGFPEBG0@Z */
2247 DEFINE_THISCALL_WRAPPER(ctype_wchar_scan_not, 16)
2248 const wchar_t* __thiscall ctype_wchar_scan_not(const ctype_wchar *this,
2249         short mask, const wchar_t *first, const wchar_t *last)
2250 {
2251     TRACE("(%p %x %p %p)\n", this, mask, first, last);
2252     return call_ctype_wchar_do_scan_not(this, mask, first, last);
2253 }
2254
2255 /* ??_7codecvt_base@std@@6B@ */
2256 extern const vtable_ptr MSVCP_codecvt_base_vtable;
2257
2258 /* ??0codecvt_base@std@@QAE@I@Z */
2259 /* ??0codecvt_base@std@@QEAA@_K@Z */
2260 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor_refs, 8)
2261 codecvt_base* __thiscall codecvt_base_ctor_refs(codecvt_base *this, MSVCP_size_t refs)
2262 {
2263     TRACE("(%p %lu)\n", this, refs);
2264     locale_facet_ctor_refs(&this->facet, refs);
2265     this->facet.vtable = &MSVCP_codecvt_base_vtable;
2266     return this;
2267 }
2268
2269 /* ??_Fcodecvt_base@std@@QAEXXZ */
2270 /* ??_Fcodecvt_base@std@@QEAAXXZ */
2271 DEFINE_THISCALL_WRAPPER(codecvt_base_ctor, 4)
2272 codecvt_base* __thiscall codecvt_base_ctor(codecvt_base *this)
2273 {
2274     return codecvt_base_ctor_refs(this, 0);
2275 }
2276
2277 /* ??1codecvt_base@std@@UAE@XZ */
2278 /* ??1codecvt_base@std@@UEAA@XZ */
2279 DEFINE_THISCALL_WRAPPER(codecvt_base_dtor, 4)
2280 void __thiscall codecvt_base_dtor(codecvt_base *this)
2281 {
2282     TRACE("(%p)\n", this);
2283     locale_facet_dtor(&this->facet);
2284 }
2285
2286 DEFINE_THISCALL_WRAPPER(codecvt_base_vector_dtor, 8)
2287 codecvt_base* __thiscall codecvt_base_vector_dtor(codecvt_base *this, unsigned int flags)
2288 {
2289     TRACE("(%p %x)\n", this, flags);
2290     if(flags & 2) {
2291         /* we have an array, with the number of elements stored before the first object */
2292         INT_PTR i, *ptr = (INT_PTR *)this-1;
2293
2294         for(i=*ptr-1; i>=0; i--)
2295             codecvt_base_dtor(this+i);
2296         MSVCRT_operator_delete(ptr);
2297     } else {
2298         codecvt_base_dtor(this);
2299         if(flags & 1)
2300             MSVCRT_operator_delete(this);
2301     }
2302
2303     return this;
2304 }
2305
2306 /* ?do_always_noconv@codecvt_base@std@@MBE_NXZ */
2307 /* ?do_always_noconv@codecvt_base@std@@MEBA_NXZ */
2308 #define call_codecvt_base_do_always_noconv(this) CALL_VTBL_FUNC(this, 4, \
2309         MSVCP_bool, (const codecvt_base*), (this))
2310 DEFINE_THISCALL_WRAPPER(codecvt_base_do_always_noconv, 4)
2311 MSVCP_bool __thiscall codecvt_base_do_always_noconv(const codecvt_base *this)
2312 {
2313     TRACE("(%p)\n", this);
2314     return TRUE;
2315 }
2316
2317 /* ?always_noconv@codecvt_base@std@@QBE_NXZ */
2318 /* ?always_noconv@codecvt_base@std@@QEBA_NXZ */
2319 DEFINE_THISCALL_WRAPPER(codecvt_base_always_noconv, 4)
2320 MSVCP_bool __thiscall codecvt_base_always_noconv(const codecvt_base *this)
2321 {
2322     TRACE("(%p)\n", this);
2323     return call_codecvt_base_do_always_noconv(this);
2324 }
2325
2326 /* ?do_max_length@codecvt_base@std@@MBEHXZ */
2327 /* ?do_max_length@codecvt_base@std@@MEBAHXZ */
2328 #define call_codecvt_base_do_max_length(this) CALL_VTBL_FUNC(this, 8, \
2329         int, (const codecvt_base*), (this))
2330 DEFINE_THISCALL_WRAPPER(codecvt_base_do_max_length, 4)
2331 int __thiscall codecvt_base_do_max_length(const codecvt_base *this)
2332 {
2333     TRACE("(%p)\n", this);
2334     return 1;
2335 }
2336
2337 /* ?max_length@codecvt_base@std@@QBEHXZ */
2338 /* ?max_length@codecvt_base@std@@QEBAHXZ */
2339 DEFINE_THISCALL_WRAPPER(codecvt_base_max_length, 4)
2340 int __thiscall codecvt_base_max_length(const codecvt_base *this)
2341 {
2342     TRACE("(%p)\n", this);
2343     return call_codecvt_base_do_max_length(this);
2344 }
2345
2346 /* ?do_encoding@codecvt_base@std@@MBEHXZ */
2347 /* ?do_encoding@codecvt_base@std@@MEBAHXZ */
2348 #define call_codecvt_base_do_encoding(this) CALL_VTBL_FUNC(this, 12, \
2349         int, (const codecvt_base*), (this))
2350 DEFINE_THISCALL_WRAPPER(codecvt_base_do_encoding, 4)
2351 int __thiscall codecvt_base_do_encoding(const codecvt_base *this)
2352 {
2353     TRACE("(%p)\n", this);
2354     return 1;
2355 }
2356
2357 /* ?encoding@codecvt_base@std@@QBEHXZ */
2358 /* ?encoding@codecvt_base@std@@QEBAHXZ */
2359 DEFINE_THISCALL_WRAPPER(codecvt_base_encoding, 4)
2360 int __thiscall codecvt_base_encoding(const codecvt_base *this)
2361 {
2362     TRACE("(%p)\n", this);
2363     return call_codecvt_base_do_encoding(this);
2364 }
2365
2366 /* ?id@?$codecvt@DDH@std@@2V0locale@2@A */
2367 locale_id codecvt_char_id = {0};
2368
2369 /* ??_7?$codecvt@DDH@std@@6B@ */
2370 extern const vtable_ptr MSVCP_codecvt_char_vtable;
2371
2372 /* ?_Init@?$codecvt@DDH@std@@IAEXABV_Locinfo@2@@Z */
2373 /* ?_Init@?$codecvt@DDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2374 DEFINE_THISCALL_WRAPPER(codecvt_char__Init, 8)
2375 void __thiscall codecvt_char__Init(codecvt_char *this, const _Locinfo *locinfo)
2376 {
2377     TRACE("(%p %p)\n", this, locinfo);
2378 }
2379
2380 /* ??0?$codecvt@DDH@std@@QAE@ABV_Locinfo@1@I@Z */
2381 /* ??0?$codecvt@DDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2382 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_locinfo, 12)
2383 codecvt_char* __thiscall codecvt_char_ctor_locinfo(codecvt_char *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2384 {
2385     TRACE("(%p %p %lu)\n", this, locinfo, refs);
2386     codecvt_base_ctor_refs(&this->base, refs);
2387     this->base.facet.vtable = &MSVCP_codecvt_char_vtable;
2388     return this;
2389 }
2390
2391 /* ??0?$codecvt@DDH@std@@QAE@I@Z */
2392 /* ??0?$codecvt@DDH@std@@QEAA@_K@Z */
2393 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor_refs, 8)
2394 codecvt_char* __thiscall codecvt_char_ctor_refs(codecvt_char *this, MSVCP_size_t refs)
2395 {
2396     return codecvt_char_ctor_locinfo(this, NULL, refs);
2397 }
2398
2399 /* ??_F?$codecvt@DDH@std@@QAEXXZ */
2400 /* ??_F?$codecvt@DDH@std@@QEAAXXZ */
2401 DEFINE_THISCALL_WRAPPER(codecvt_char_ctor, 4)
2402 codecvt_char* __thiscall codecvt_char_ctor(codecvt_char *this)
2403 {
2404     return codecvt_char_ctor_locinfo(this, NULL, 0);
2405 }
2406
2407 /* ??1?$codecvt@DDH@std@@MAE@XZ */
2408 /* ??1?$codecvt@DDH@std@@MEAA@XZ */
2409 static void codecvt_char_dtor(codecvt_char *this)
2410 {
2411     TRACE("(%p)\n", this);
2412     codecvt_base_dtor(&this->base);
2413 }
2414
2415 DEFINE_THISCALL_WRAPPER(codecvt_char_vector_dtor, 8)
2416 codecvt_char* __thiscall codecvt_char_vector_dtor(codecvt_char *this, unsigned int flags)
2417 {
2418     TRACE("(%p %x)\n", this, flags);
2419     if(flags & 2) {
2420         /* we have an array, with the number of elements stored before the first object */
2421         INT_PTR i, *ptr = (INT_PTR *)this-1;
2422
2423         for(i=*ptr-1; i>=0; i--)
2424             codecvt_char_dtor(this+i);
2425         MSVCRT_operator_delete(ptr);
2426     } else {
2427         codecvt_char_dtor(this);
2428         if(flags & 1)
2429             MSVCRT_operator_delete(this);
2430     }
2431
2432     return this;
2433 }
2434
2435 /* ?_Getcat@?$codecvt@DDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2436 /* ?_Getcat@?$codecvt@DDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2437 static MSVCP_size_t codecvt_char__Getcat(const locale_facet **facet, const locale *loc)
2438 {
2439     TRACE("(%p %p)\n", facet, loc);
2440
2441     if(facet && !*facet) {
2442         *facet = MSVCRT_operator_new(sizeof(codecvt_char));
2443         if(!*facet) {
2444             ERR("Out of memory\n");
2445             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2446             return 0;
2447         }
2448         codecvt_char_ctor((codecvt_char*)*facet);
2449     }
2450
2451     return LC_CTYPE;
2452 }
2453
2454 codecvt_char* codecvt_char_use_facet(const locale *loc)
2455 {
2456     static codecvt_char *obj = NULL;
2457
2458     _Lockit lock;
2459     const locale_facet *fac;
2460
2461     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2462     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_char_id));
2463     if(fac) {
2464         _Lockit_dtor(&lock);
2465         return (codecvt_char*)fac;
2466     }
2467
2468     if(obj) {
2469         _Lockit_dtor(&lock);
2470         return obj;
2471     }
2472
2473     codecvt_char__Getcat(&fac, loc);
2474     obj = (codecvt_char*)fac;
2475     locale_facet__Incref(&obj->base.facet);
2476     locale_facet_register(&obj->base.facet);
2477     _Lockit_dtor(&lock);
2478
2479     return obj;
2480 }
2481
2482 /* ?do_in@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2483 /* ?do_in@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2484 #define call_codecvt_char_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
2485     CALL_VTBL_FUNC(this, 16, int, \
2486             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2487             (this, state, from, from_end, from_next, to, to_end, to_next))
2488 DEFINE_THISCALL_WRAPPER(codecvt_char_do_in, 32)
2489 int __thiscall codecvt_char_do_in(const codecvt_char *this, int *state,
2490         const char *from, const char *from_end, const char **from_next,
2491         char *to, char *to_end, char **to_next)
2492 {
2493     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2494             from_next, to, to_end, to_next);
2495     *from_next = from;
2496     *to_next = to;
2497     return CODECVT_noconv;
2498 }
2499
2500 /* ?in@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2501 /* ?in@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2502 DEFINE_THISCALL_WRAPPER(codecvt_char_in, 32)
2503 int __thiscall codecvt_char_in(const codecvt_char *this, int *state,
2504         const char *from, const char *from_end, const char **from_next,
2505         char *to, char *to_end, char **to_next)
2506 {
2507     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2508             from_next, to, to_end, to_next);
2509     return call_codecvt_char_do_in(this, state, from, from_end, from_next,
2510             to, to_end, to_next);
2511 }
2512
2513 /* ?do_out@?$codecvt@DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2514 /* ?do_out@?$codecvt@DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2515 #define call_codecvt_char_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
2516     CALL_VTBL_FUNC(this, 20, int, \
2517             (const codecvt_char*, int*, const char*, const char*, const char**, char*, char*, char**), \
2518             (this, state, from, from_end, from_next, to, to_end, to_next))
2519 DEFINE_THISCALL_WRAPPER(codecvt_char_do_out, 32)
2520 int __thiscall codecvt_char_do_out(const codecvt_char *this, int *state,
2521         const char *from, const char *from_end, const char **from_next,
2522         char *to, char *to_end, char **to_next)
2523 {
2524     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2525             from_end, from_next, to, to_end, to_next);
2526     *from_next = from;
2527     *to_next = to;
2528     return CODECVT_noconv;
2529 }
2530
2531 /* ?out@?$codecvt@DDH@std@@QBEHAAHPBD1AAPBDPAD3AAPAD@Z */
2532 /* ?out@?$codecvt@DDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD@Z */
2533 DEFINE_THISCALL_WRAPPER(codecvt_char_out, 32)
2534 int __thiscall codecvt_char_out(const codecvt_char *this, int *state,
2535         const char *from, const char *from_end, const char **from_next,
2536         char *to, char *to_end, char **to_next)
2537 {
2538     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from, from_end,
2539             from_next, to, to_end, to_next);
2540     return call_codecvt_char_do_out(this, state, from, from_end, from_next,
2541             to, to_end, to_next);
2542 }
2543
2544 /* ?do_unshift@?$codecvt@DDH@std@@MBEHAAHPAD1AAPAD@Z */
2545 /* ?do_unshift@?$codecvt@DDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2546 #define call_codecvt_char_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
2547         int, (const codecvt_char*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
2548 DEFINE_THISCALL_WRAPPER(codecvt_char_do_unshift, 20)
2549 int __thiscall codecvt_char_do_unshift(const codecvt_char *this,
2550         int *state, char *to, char *to_end, char **to_next)
2551 {
2552     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2553     *to_next = to;
2554     return CODECVT_noconv;
2555 }
2556
2557 /* ?unshift@?$codecvt@DDH@std@@QBEHAAHPAD1AAPAD@Z */
2558 /* ?unshift@?$codecvt@DDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2559 int codecvt_char_unshift(const codecvt_char *this,
2560         int *state, char *to, char *to_end, char **to_next)
2561 {
2562     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2563     return call_codecvt_char_do_unshift(this, state, to, to_end, to_next);
2564 }
2565
2566 /* ?do_length@?$codecvt@DDH@std@@MBEHABHPBD1I@Z */
2567 /* ?do_length@?$codecvt@DDH@std@@MEBAHAEBHPEBD1_K@Z */
2568 #define call_codecvt_char_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
2569         int, (const codecvt_char*, const int*, const char*, const char*, MSVCP_size_t), \
2570         (this, state, from, from_end, max))
2571 DEFINE_THISCALL_WRAPPER(codecvt_char_do_length, 20)
2572 int __thiscall codecvt_char_do_length(const codecvt_char *this, const int *state,
2573         const char *from, const char *from_end, MSVCP_size_t max)
2574 {
2575     TRACE("(%p %p %p %p %lu)\n", this, state, from, from_end, max);
2576     return (from_end-from > max ? max : from_end-from);
2577 }
2578
2579 /* ?id@?$codecvt@_WDH@std@@2V0locale@2@A */
2580 static locale_id codecvt_wchar_id = {0};
2581 /* ?id@?$codecvt@GDH@std@@2V0locale@2@A */
2582 locale_id codecvt_short_id = {0};
2583
2584 /* ??_7?$codecvt@_WDH@std@@6B@ */
2585 extern const vtable_ptr MSVCP_codecvt_wchar_vtable;
2586 /* ??_7?$codecvt@GDH@std@@6B@ */
2587 extern const vtable_ptr MSVCP_codecvt_short_vtable;
2588
2589 /* ?_Init@?$codecvt@GDH@std@@IAEXABV_Locinfo@2@@Z */
2590 /* ?_Init@?$codecvt@GDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2591 /* ?_Init@?$codecvt@_WDH@std@@IAEXABV_Locinfo@2@@Z */
2592 /* ?_Init@?$codecvt@_WDH@std@@IEAAXAEBV_Locinfo@2@@Z */
2593 DEFINE_THISCALL_WRAPPER(codecvt_wchar__Init, 8)
2594 void __thiscall codecvt_wchar__Init(codecvt_wchar *this, const _Locinfo *locinfo)
2595 {
2596     TRACE("(%p %p)\n", this, locinfo);
2597     _Locinfo__Getcvt(locinfo, &this->cvt);
2598 }
2599
2600 /* ??0?$codecvt@_WDH@std@@QAE@ABV_Locinfo@1@I@Z */
2601 /* ??0?$codecvt@_WDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2602 static codecvt_wchar* codecvt_wchar_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2603 {
2604     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2605
2606     codecvt_base_ctor_refs(&this->base, refs);
2607     this->base.facet.vtable = &MSVCP_codecvt_wchar_vtable;
2608
2609     codecvt_wchar__Init(this, locinfo);
2610     return this;
2611 }
2612
2613 /* ??0?$codecvt@GDH@std@@QAE@ABV_Locinfo@1@I@Z */
2614 /* ??0?$codecvt@GDH@std@@QEAA@AEBV_Locinfo@1@_K@Z */
2615 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_locinfo, 12)
2616 codecvt_wchar* __thiscall codecvt_short_ctor_locinfo(codecvt_wchar *this, const _Locinfo *locinfo, MSVCP_size_t refs)
2617 {
2618     TRACE("(%p %p %ld)\n", this, locinfo, refs);
2619
2620     codecvt_wchar_ctor_locinfo(this, locinfo, refs);
2621     this->base.facet.vtable = &MSVCP_codecvt_short_vtable;
2622     return this;
2623 }
2624
2625 /* ??0?$codecvt@GDH@std@@QAE@I@Z */
2626 /* ??0?$codecvt@GDH@std@@QEAA@_K@Z */
2627 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor_refs, 8)
2628 codecvt_wchar* __thiscall codecvt_short_ctor_refs(codecvt_wchar *this, MSVCP_size_t refs)
2629 {
2630     _Locinfo locinfo;
2631
2632     TRACE("(%p %ld)\n", this, refs);
2633
2634     _Locinfo_ctor(&locinfo);
2635     codecvt_short_ctor_locinfo(this, &locinfo, refs);
2636     _Locinfo_dtor(&locinfo);
2637     return this;
2638 }
2639
2640 /* ??_F?$codecvt@GDH@std@@QAEXXZ */
2641 /* ??_F?$codecvt@GDH@std@@QEAAXXZ */
2642 DEFINE_THISCALL_WRAPPER(codecvt_short_ctor, 4)
2643 codecvt_wchar* __thiscall codecvt_short_ctor(codecvt_wchar *this)
2644 {
2645     return codecvt_short_ctor_refs(this, 0);
2646 }
2647
2648 /* ??1?$codecvt@GDH@std@@MAE@XZ */
2649 /* ??1?$codecvt@GDH@std@@MEAA@XZ */
2650 /* ??1?$codecvt@_WDH@std@@MAE@XZ */
2651 /* ??1?$codecvt@_WDH@std@@MEAA@XZ */
2652 static void codecvt_wchar_dtor(codecvt_wchar *this)
2653 {
2654     TRACE("(%p)\n", this);
2655     codecvt_base_dtor(&this->base);
2656 }
2657
2658 DEFINE_THISCALL_WRAPPER(codecvt_wchar_vector_dtor, 8)
2659 codecvt_wchar* __thiscall codecvt_wchar_vector_dtor(codecvt_wchar *this, unsigned int flags)
2660 {
2661     TRACE("(%p %x)\n", this, flags);
2662     if(flags & 2) {
2663         /* we have an array, with the number of elements stored before the first object */
2664         INT_PTR i, *ptr = (INT_PTR *)this-1;
2665
2666         for(i=*ptr-1; i>=0; i--)
2667             codecvt_wchar_dtor(this+i);
2668         MSVCRT_operator_delete(ptr);
2669     } else {
2670         codecvt_wchar_dtor(this);
2671         if(flags & 1)
2672             MSVCRT_operator_delete(this);
2673     }
2674
2675     return this;
2676 }
2677
2678 /* ?_Getcat@?$codecvt@_WDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2679 /* ?_Getcat@?$codecvt@_WDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2680 static MSVCP_size_t codecvt_wchar__Getcat(const locale_facet **facet, const locale *loc)
2681 {
2682     TRACE("(%p %p)\n", facet, loc);
2683
2684     if(facet && !*facet) {
2685         _Locinfo locinfo;
2686
2687         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
2688         if(!*facet) {
2689             ERR("Out of memory\n");
2690             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2691             return 0;
2692         }
2693
2694         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
2695         codecvt_wchar_ctor_locinfo((codecvt_wchar*)*facet, &locinfo, 0);
2696         _Locinfo_dtor(&locinfo);
2697     }
2698
2699     return LC_CTYPE;
2700 }
2701
2702 codecvt_wchar* codecvt_wchar_use_facet(const locale *loc)
2703 {
2704     static codecvt_wchar *obj = NULL;
2705
2706     _Lockit lock;
2707     const locale_facet *fac;
2708
2709     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2710     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_wchar_id));
2711     if(fac) {
2712         _Lockit_dtor(&lock);
2713         return (codecvt_wchar*)fac;
2714     }
2715
2716     if(obj) {
2717         _Lockit_dtor(&lock);
2718         return obj;
2719     }
2720
2721     codecvt_wchar__Getcat(&fac, loc);
2722     obj = (codecvt_wchar*)fac;
2723     locale_facet__Incref(&obj->base.facet);
2724     locale_facet_register(&obj->base.facet);
2725     _Lockit_dtor(&lock);
2726
2727     return obj;
2728 }
2729
2730 /* ?_Getcat@?$codecvt@GDH@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
2731 /* ?_Getcat@?$codecvt@GDH@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
2732 static MSVCP_size_t codecvt_short__Getcat(const locale_facet **facet, const locale *loc)
2733 {
2734     TRACE("(%p %p)\n", facet, loc);
2735
2736     if(facet && !*facet) {
2737         _Locinfo locinfo;
2738
2739         *facet = MSVCRT_operator_new(sizeof(codecvt_wchar));
2740         if(!*facet) {
2741             ERR("Out of memory\n");
2742             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
2743             return 0;
2744         }
2745
2746         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
2747         codecvt_short_ctor((codecvt_wchar*)*facet);
2748         _Locinfo_dtor(&locinfo);
2749     }
2750
2751     return LC_CTYPE;
2752 }
2753
2754 codecvt_wchar* codecvt_short_use_facet(const locale *loc)
2755 {
2756     static codecvt_wchar *obj = NULL;
2757
2758     _Lockit lock;
2759     const locale_facet *fac;
2760
2761     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
2762     fac = locale__Getfacet(loc, locale_id_operator_size_t(&codecvt_short_id));
2763     if(fac) {
2764         _Lockit_dtor(&lock);
2765         return (codecvt_wchar*)fac;
2766     }
2767
2768     if(obj) {
2769         _Lockit_dtor(&lock);
2770         return obj;
2771     }
2772
2773     codecvt_short__Getcat(&fac, loc);
2774     obj = (codecvt_wchar*)fac;
2775     locale_facet__Incref(&obj->base.facet);
2776     locale_facet_register(&obj->base.facet);
2777     _Lockit_dtor(&lock);
2778
2779     return obj;
2780 }
2781
2782 /* ?do_always_noconv@?$codecvt@GDH@std@@MBE_NXZ */
2783 /* ?do_always_noconv@?$codecvt@GDH@std@@MEBA_NXZ */
2784 /* ?do_always_noconv@?$codecvt@_WDH@std@@MBE_NXZ */
2785 /* ?do_always_noconv@?$codecvt@_WDH@std@@MEBA_NXZ */
2786 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_always_noconv, 4)
2787 MSVCP_bool __thiscall codecvt_wchar_do_always_noconv(const codecvt_wchar *this)
2788 {
2789     TRACE("(%p)\n", this);
2790     return FALSE;
2791 }
2792
2793 /* ?do_max_length@?$codecvt@GDH@std@@MBEHXZ */
2794 /* ?do_max_length@?$codecvt@GDH@std@@MEBAHXZ */
2795 /* ?do_max_length@?$codecvt@_WDH@std@@MBEHXZ */
2796 /* ?do_max_length@?$codecvt@_WDH@std@@MEBAHXZ */
2797 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_max_length, 4)
2798 int __thiscall codecvt_wchar_do_max_length(const codecvt_wchar *this)
2799 {
2800     TRACE("(%p)\n", this);
2801     return MB_LEN_MAX;
2802 }
2803
2804 /* ?do_in@?$codecvt@GDH@std@@MBEHAAHPBD1AAPBDPAG3AAPAG@Z */
2805 /* ?do_in@?$codecvt@GDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
2806 /* ?do_in@?$codecvt@_WDH@std@@MBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
2807 /* ?do_in@?$codecvt@_WDH@std@@MEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
2808 #define call_codecvt_wchar_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
2809     CALL_VTBL_FUNC(this, 16, int, \
2810             (const codecvt_wchar*, int*, const char*, const char*, const char**, wchar_t*, wchar_t*, wchar_t**), \
2811             (this, state, from, from_end, from_next, to, to_end, to_next))
2812 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_in, 32)
2813 int __thiscall codecvt_wchar_do_in(const codecvt_wchar *this, int *state,
2814         const char *from, const char *from_end, const char **from_next,
2815         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
2816 {
2817     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2818             from_end, from_next, to, to_end, to_next);
2819
2820     *from_next = from;
2821     *to_next = to;
2822
2823     while(*from_next!=from_end && *to_next!=to_end) {
2824         switch(_Mbrtowc(*to_next, *from_next, from_end-*from_next, state, &this->cvt)) {
2825         case -2:
2826             *from_next = from_end;
2827             return CODECVT_partial;
2828         case -1:
2829             return CODECVT_error;
2830         case 2:
2831             (*from_next)++;
2832             /* fall through */
2833         case 0:
2834         case 1:
2835             (*from_next)++;
2836             (*to_next)++;
2837         }
2838     }
2839
2840     return CODECVT_ok;
2841 }
2842
2843 /* ?in@?$codecvt@GDH@std@@QBEHAAHPBD1AAPBDPAG3AAPAG@Z */
2844 /* ?in@?$codecvt@GDH@std@@QEBAHAEAHPEBD1AEAPEBDPEAG3AEAPEAG@Z */
2845 /* ?in@?$codecvt@_WDH@std@@QBEHAAHPBD1AAPBDPA_W3AAPA_W@Z */
2846 /* ?in@?$codecvt@_WDH@std@@QEBAHAEAHPEBD1AEAPEBDPEA_W3AEAPEA_W@Z */
2847 DEFINE_THISCALL_WRAPPER(codecvt_wchar_in, 32)
2848 int __thiscall codecvt_wchar_in(const codecvt_wchar *this, int *state,
2849         const char *from, const char *from_end, const char **from_next,
2850         wchar_t *to, wchar_t *to_end, wchar_t **to_next)
2851 {
2852     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2853             from_end, from_next, to, to_end, to_next);
2854     return call_codecvt_wchar_do_in(this, state, from,
2855             from_end, from_next, to, to_end, to_next);
2856 }
2857
2858 /* ?do_out@?$codecvt@GDH@std@@MBEHAAHPBG1AAPBGPAD3AAPAD@Z */
2859 /* ?do_out@?$codecvt@GDH@std@@MEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
2860 /* ?do_out@?$codecvt@_WDH@std@@MBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
2861 /* ?do_out@?$codecvt@_WDH@std@@MEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
2862 #define call_codecvt_wchar_do_out(this, state, from, from_end, from_next, to, to_end, to_next) \
2863     CALL_VTBL_FUNC(this, 20, int, \
2864             (const codecvt_wchar*, int*, const wchar_t*, const wchar_t*, const wchar_t**, char*, char*, char**), \
2865             (this, state, from, from_end, from_next, to, to_end, to_next))
2866 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_out, 32)
2867 int __thiscall codecvt_wchar_do_out(const codecvt_wchar *this, int *state,
2868         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
2869         char *to, char *to_end, char **to_next)
2870 {
2871     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2872             from_end, from_next, to, to_end, to_next);
2873
2874     *from_next = from;
2875     *to_next = to;
2876
2877     while(*from_next!=from_end && *to_next!=to_end) {
2878         int old_state = *state, size;
2879         char buf[MB_LEN_MAX];
2880
2881         switch((size = _Wcrtomb(buf, **from_next, state, &this->cvt))) {
2882         case -1:
2883             return CODECVT_error;
2884         default:
2885             if(size > from_end-*from_next) {
2886                 *state = old_state;
2887                 return CODECVT_partial;
2888             }
2889
2890             (*from_next)++;
2891             memcpy_s(*to_next, to_end-*to_next, buf, size);
2892             (*to_next) += size;
2893         }
2894     }
2895
2896     return CODECVT_ok;
2897 }
2898
2899 /* ?out@?$codecvt@GDH@std@@QBEHAAHPBG1AAPBGPAD3AAPAD@Z */
2900 /* ?out@?$codecvt@GDH@std@@QEBAHAEAHPEBG1AEAPEBGPEAD3AEAPEAD@Z */
2901 /* ?out@?$codecvt@_WDH@std@@QBEHAAHPB_W1AAPB_WPAD3AAPAD@Z */
2902 /* ?out@?$codecvt@_WDH@std@@QEBAHAEAHPEB_W1AEAPEB_WPEAD3AEAPEAD@Z */
2903 DEFINE_THISCALL_WRAPPER(codecvt_wchar_out, 32)
2904 int __thiscall codecvt_wchar_out(const codecvt_wchar *this, int *state,
2905         const wchar_t *from, const wchar_t *from_end, const wchar_t **from_next,
2906         char *to, char *to_end, char **to_next)
2907 {
2908     TRACE("(%p %p %p %p %p %p %p %p)\n", this, state, from,
2909             from_end, from_next, to, to_end, to_next);
2910     return call_codecvt_wchar_do_out(this, state, from,
2911             from_end, from_next, to, to_end, to_next);
2912 }
2913
2914 /* ?do_unshift@?$codecvt@GDH@std@@MBEHAAHPAD1AAPAD@Z */
2915 /* ?do_unshift@?$codecvt@GDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2916 /* ?do_unshift@?$codecvt@_WDH@std@@MBEHAAHPAD1AAPAD@Z */
2917 /* ?do_unshift@?$codecvt@_WDH@std@@MEBAHAEAHPEAD1AEAPEAD@Z */
2918 #define call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next) CALL_VTBL_FUNC(this, 24, \
2919         int, (const codecvt_wchar*, int*, char*, char*, char**), (this, state, to, to_end, to_next))
2920 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_unshift, 20)
2921 int __thiscall codecvt_wchar_do_unshift(const codecvt_wchar *this,
2922         int *state, char *to, char *to_end, char **to_next)
2923 {
2924     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2925     if(*state)
2926         WARN("unexpected state: %x\n", *state);
2927
2928     *to_next = to;
2929     return CODECVT_ok;
2930 }
2931
2932 /* ?unshift@?$codecvt@GDH@std@@QBEHAAHPAD1AAPAD@Z */
2933 /* ?unshift@?$codecvt@GDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2934 /* ?unshift@?$codecvt@_WDH@std@@QBEHAAHPAD1AAPAD@Z */
2935 /* ?unshift@?$codecvt@_WDH@std@@QEBAHAEAHPEAD1AEAPEAD@Z */
2936 int codecvt_wchar_unshift(const codecvt_wchar *this,
2937         int *state, char *to, char *to_end, char **to_next)
2938 {
2939     TRACE("(%p %p %p %p %p)\n", this, state, to, to_end, to_next);
2940     return call_codecvt_wchar_do_unshift(this, state, to, to_end, to_next);
2941 }
2942
2943 /* ?do_length@?$codecvt@GDH@std@@MBEHABHPBD1I@Z */
2944 /* ?do_length@?$codecvt@GDH@std@@MEBAHAEBHPEBD1_K@Z */
2945 /* ?do_length@?$codecvt@_WDH@std@@MBEHABHPBD1I@Z */
2946 /* ?do_length@?$codecvt@_WDH@std@@MEBAHAEBHPEBD1_K@Z */
2947 #define call_codecvt_wchar_do_length(this, state, from, from_end, max) CALL_VTBL_FUNC(this, 28, \
2948         int, (const codecvt_wchar*, const int*, const char*, const char*, MSVCP_size_t), \
2949         (this, state, from, from_end, max))
2950 DEFINE_THISCALL_WRAPPER(codecvt_wchar_do_length, 20)
2951 int __thiscall codecvt_wchar_do_length(const codecvt_wchar *this, const int *state,
2952         const char *from, const char *from_end, MSVCP_size_t max)
2953 {
2954     int tmp_state = *state, ret=0;
2955
2956     TRACE("(%p %p %p %p %ld)\n", this, state, from, from_end, max);
2957
2958     while(ret<max && from!=from_end) {
2959         switch(_Mbrtowc(NULL, from, from_end-from, &tmp_state, &this->cvt)) {
2960         case -2:
2961         case -1:
2962             return ret;
2963         case 2:
2964             from++;
2965             /* fall through */
2966         case 0:
2967         case 1:
2968             from++;
2969             ret++;
2970         }
2971     }
2972
2973     return ret;
2974 }
2975
2976 /* ?id@?$numpunct@D@std@@2V0locale@2@A */
2977 locale_id numpunct_char_id = {0};
2978
2979 /* ??_7?$numpunct@D@std@@6B@ */
2980 extern const vtable_ptr MSVCP_numpunct_char_vtable;
2981
2982 /* ?_Init@?$numpunct@D@std@@IAEXABV_Locinfo@2@_N@Z */
2983 /* ?_Init@?$numpunct@D@std@@IEAAXAEBV_Locinfo@2@_N@Z */
2984 static void numpunct_char__Init(numpunct_char *this, const _Locinfo *locinfo, MSVCP_bool isdef)
2985 {
2986     int len;
2987
2988     TRACE("(%p %p %d)\n", this, locinfo, isdef);
2989
2990     len = strlen(_Locinfo__Getfalse(locinfo))+1;
2991     this->false_name = MSVCRT_operator_new(len);
2992     if(this->false_name)
2993         memcpy((char*)this->false_name, _Locinfo__Getfalse(locinfo), len);
2994
2995     len = strlen(_Locinfo__Gettrue(locinfo))+1;
2996     this->true_name = MSVCRT_operator_new(len);
2997     if(this->true_name)
2998         memcpy((char*)this->true_name, _Locinfo__Gettrue(locinfo), len);
2999
3000     if(isdef) {
3001         this->grouping = MSVCRT_operator_new(1);
3002         if(this->grouping)
3003             *(char*)this->grouping = 0;
3004
3005         this->dp = '.';
3006         this->sep = ',';
3007     } else {
3008         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3009
3010         len = strlen(lc->grouping)+1;
3011         this->grouping = MSVCRT_operator_new(len);
3012         if(this->grouping)
3013             memcpy((char*)this->grouping, lc->grouping, len);
3014
3015         this->dp = lc->decimal_point[0];
3016         this->sep = lc->thousands_sep[0];
3017     }
3018
3019     if(!this->false_name || !this->true_name || !this->grouping) {
3020         MSVCRT_operator_delete((char*)this->grouping);
3021         MSVCRT_operator_delete((char*)this->false_name);
3022         MSVCRT_operator_delete((char*)this->true_name);
3023
3024         ERR("Out of memory\n");
3025         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3026     }
3027 }
3028
3029 /* ?_Tidy@?$numpunct@D@std@@AAEXXZ */
3030 /* ?_Tidy@?$numpunct@D@std@@AEAAXXZ */
3031 static void numpunct_char__Tidy(numpunct_char *this)
3032 {
3033     TRACE("(%p)\n", this);
3034
3035     MSVCRT_operator_delete((char*)this->grouping);
3036     MSVCRT_operator_delete((char*)this->false_name);
3037     MSVCRT_operator_delete((char*)this->true_name);
3038 }
3039
3040 /* ??0?$numpunct@D@std@@QAE@ABV_Locinfo@1@I_N@Z */
3041 /* ??0?$numpunct@D@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3042 static numpunct_char* numpunct_char_ctor_locinfo(numpunct_char *this,
3043         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3044 {
3045     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3046     locale_facet_ctor_refs(&this->facet, refs);
3047     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3048     numpunct_char__Init(this, locinfo, usedef);
3049     return this;
3050 }
3051
3052 /* ??0?$numpunct@D@std@@IAE@PBDI_N@Z */
3053 /* ??0?$numpunct@D@std@@IEAA@PEBD_K_N@Z */
3054 static numpunct_char* numpunct_char_ctor_name(numpunct_char *this,
3055         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3056 {
3057     _Locinfo locinfo;
3058
3059     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3060     locale_facet_ctor_refs(&this->facet, refs);
3061     this->facet.vtable = &MSVCP_numpunct_char_vtable;
3062
3063     _Locinfo_ctor_cstr(&locinfo, name);
3064     numpunct_char__Init(this, &locinfo, usedef);
3065     _Locinfo_dtor(&locinfo);
3066     return this;
3067 }
3068
3069 /* ??0?$numpunct@D@std@@QAE@I@Z */
3070 /* ??0?$numpunct@D@std@@QEAA@_K@Z */
3071 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor_refs, 8)
3072 numpunct_char* __thiscall numpunct_char_ctor_refs(numpunct_char *this, MSVCP_size_t refs)
3073 {
3074     TRACE("(%p %lu)\n", this, refs);
3075     return numpunct_char_ctor_name(this, "C", refs, FALSE);
3076 }
3077
3078 /* ??_F?$numpunct@D@std@@QAEXXZ */
3079 /* ??_F?$numpunct@D@std@@QEAAXXZ */
3080 DEFINE_THISCALL_WRAPPER(numpunct_char_ctor, 4)
3081 numpunct_char* __thiscall numpunct_char_ctor(numpunct_char *this)
3082 {
3083     return numpunct_char_ctor_refs(this, 0);
3084 }
3085
3086 /* ??1?$numpunct@D@std@@MAE@XZ */
3087 /* ??1?$numpunct@D@std@@MEAA@XZ */
3088 static void numpunct_char_dtor(numpunct_char *this)
3089 {
3090     TRACE("(%p)\n", this);
3091     numpunct_char__Tidy(this);
3092 }
3093
3094 DEFINE_THISCALL_WRAPPER(numpunct_char_vector_dtor, 8)
3095 numpunct_char* __thiscall numpunct_char_vector_dtor(numpunct_char *this, unsigned int flags)
3096 {
3097     TRACE("(%p %x)\n", this, flags);
3098     if(flags & 2) {
3099         /* we have an array, with the number of elements stored before the first object */
3100         INT_PTR i, *ptr = (INT_PTR *)this-1;
3101
3102         for(i=*ptr-1; i>=0; i--)
3103             numpunct_char_dtor(this+i);
3104         MSVCRT_operator_delete(ptr);
3105     } else {
3106         numpunct_char_dtor(this);
3107         if(flags & 1)
3108             MSVCRT_operator_delete(this);
3109     }
3110
3111     return this;
3112 }
3113
3114 /* ?_Getcat@?$numpunct@D@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3115 /* ?_Getcat@?$numpunct@D@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3116 static MSVCP_size_t numpunct_char__Getcat(const locale_facet **facet, const locale *loc)
3117 {
3118     TRACE("(%p %p)\n", facet, loc);
3119
3120     if(facet && !*facet) {
3121         *facet = MSVCRT_operator_new(sizeof(numpunct_char));
3122         if(!*facet) {
3123             ERR("Out of memory\n");
3124             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3125             return 0;
3126         }
3127         numpunct_char_ctor_name((numpunct_char*)*facet,
3128                 basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3129     }
3130
3131     return LC_NUMERIC;
3132 }
3133
3134 static numpunct_char* numpunct_char_use_facet(const locale *loc)
3135 {
3136     static numpunct_char *obj = NULL;
3137
3138     _Lockit lock;
3139     const locale_facet *fac;
3140
3141     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3142     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_char_id));
3143     if(fac) {
3144         _Lockit_dtor(&lock);
3145         return (numpunct_char*)fac;
3146     }
3147
3148     if(obj) {
3149         _Lockit_dtor(&lock);
3150         return obj;
3151     }
3152
3153     numpunct_char__Getcat(&fac, loc);
3154     obj = (numpunct_char*)fac;
3155     locale_facet__Incref(&obj->facet);
3156     locale_facet_register(&obj->facet);
3157     _Lockit_dtor(&lock);
3158
3159     return obj;
3160 }
3161
3162 /* ?do_decimal_point@?$numpunct@D@std@@MBEDXZ */
3163 /* ?do_decimal_point@?$numpunct@D@std@@MEBADXZ */
3164 DEFINE_THISCALL_WRAPPER(numpunct_char_do_decimal_point, 4)
3165 #define call_numpunct_char_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3166         char, (const numpunct_char *this), (this))
3167 char __thiscall numpunct_char_do_decimal_point(const numpunct_char *this)
3168 {
3169     TRACE("(%p)\n", this);
3170     return this->dp;
3171 }
3172
3173 /* ?decimal_point@?$numpunct@D@std@@QBEDXZ */
3174 /* ?decimal_point@?$numpunct@D@std@@QEBADXZ */
3175 DEFINE_THISCALL_WRAPPER(numpunct_char_decimal_point, 4)
3176 char __thiscall numpunct_char_decimal_point(const numpunct_char *this)
3177 {
3178     TRACE("(%p)\n", this);
3179     return call_numpunct_char_do_decimal_point(this);
3180 }
3181
3182 /* ?do_thousands_sep@?$numpunct@D@std@@MBEDXZ */
3183 /* ?do_thousands_sep@?$numpunct@D@std@@MEBADXZ */
3184 DEFINE_THISCALL_WRAPPER(numpunct_char_do_thousands_sep, 4)
3185 #define call_numpunct_char_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3186         char, (const numpunct_char*), (this))
3187 char __thiscall numpunct_char_do_thousands_sep(const numpunct_char *this)
3188 {
3189     TRACE("(%p)\n", this);
3190     return this->sep;
3191 }
3192
3193 /* ?thousands_sep@?$numpunct@D@std@@QBEDXZ */
3194 /* ?thousands_sep@?$numpunct@D@std@@QEBADXZ */
3195 DEFINE_THISCALL_WRAPPER(numpunct_char_thousands_sep, 4)
3196 char __thiscall numpunct_char_thousands_sep(const numpunct_char *this)
3197 {
3198     TRACE("(%p)\n", this);
3199     return call_numpunct_char_do_thousands_sep(this);
3200 }
3201
3202 /* ?do_grouping@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3203 /* ?do_grouping@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3204 DEFINE_THISCALL_WRAPPER(numpunct_char_do_grouping, 8)
3205 #define call_numpunct_char_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3206         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3207 basic_string_char* __thiscall numpunct_char_do_grouping(
3208         const numpunct_char *this, basic_string_char *ret)
3209 {
3210     TRACE("(%p)\n", this);
3211     return basic_string_char_ctor_cstr(ret, this->grouping);
3212 }
3213
3214 /* ?grouping@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3215 /* ?grouping@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3216 DEFINE_THISCALL_WRAPPER(numpunct_char_grouping, 8)
3217 basic_string_char* __thiscall numpunct_char_grouping(const numpunct_char *this, basic_string_char *ret)
3218 {
3219     TRACE("(%p)\n", this);
3220     return call_numpunct_char_do_grouping(this, ret);
3221 }
3222
3223 /* ?do_falsename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3224 /* ?do_falsename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3225 DEFINE_THISCALL_WRAPPER(numpunct_char_do_falsename, 8)
3226 #define call_numpunct_char_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3227         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3228 basic_string_char* __thiscall numpunct_char_do_falsename(
3229         const numpunct_char *this, basic_string_char *ret)
3230 {
3231     TRACE("(%p)\n", this);
3232     return basic_string_char_ctor_cstr(ret, this->false_name);
3233 }
3234
3235 /* ?falsename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3236 /* ?falsename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3237 DEFINE_THISCALL_WRAPPER(numpunct_char_falsename, 8)
3238 basic_string_char* __thiscall numpunct_char_falsename(const numpunct_char *this, basic_string_char *ret)
3239 {
3240     TRACE("(%p)\n", this);
3241     return call_numpunct_char_do_falsename(this, ret);
3242 }
3243
3244 /* ?do_truename@?$numpunct@D@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3245 /* ?do_truename@?$numpunct@D@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3246 DEFINE_THISCALL_WRAPPER(numpunct_char_do_truename, 8)
3247 #define call_numpunct_char_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3248         basic_string_char*, (const numpunct_char*, basic_string_char*), (this, ret))
3249 basic_string_char* __thiscall numpunct_char_do_truename(
3250         const numpunct_char *this, basic_string_char *ret)
3251 {
3252     TRACE("(%p)\n", this);
3253     return basic_string_char_ctor_cstr(ret, this->true_name);
3254 }
3255
3256 /* ?truename@?$numpunct@D@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3257 /* ?truename@?$numpunct@D@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3258 DEFINE_THISCALL_WRAPPER(numpunct_char_truename, 8)
3259 basic_string_char* __thiscall numpunct_char_truename(const numpunct_char *this, basic_string_char *ret)
3260 {
3261     TRACE("(%p)\n", this);
3262     return call_numpunct_char_do_truename(this, ret);
3263 }
3264
3265 /* ?id@?$numpunct@_W@std@@2V0locale@2@A */
3266 static locale_id numpunct_wchar_id = {0};
3267 /* ?id@?$numpunct@G@std@@2V0locale@2@A */
3268 locale_id numpunct_short_id = {0};
3269
3270 /* ??_7?$numpunct@_W@std@@6B@ */
3271 extern const vtable_ptr MSVCP_numpunct_wchar_vtable;
3272 /* ??_7?$numpunct@G@std@@6B@ */
3273 extern const vtable_ptr MSVCP_numpunct_short_vtable;
3274
3275 /* ?_Init@?$numpunct@_W@std@@IAEXABV_Locinfo@2@_N@Z */
3276 /* ?_Init@?$numpunct@_W@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3277 /* ?_Init@?$numpunct@G@std@@IAEXABV_Locinfo@2@_N@Z */
3278 /* ?_Init@?$numpunct@G@std@@IEAAXAEBV_Locinfo@2@_N@Z */
3279 static void numpunct_wchar__Init(numpunct_wchar *this,
3280         const _Locinfo *locinfo, MSVCP_bool isdef)
3281 {
3282     const char *to_convert;
3283     _Cvtvec cvt;
3284     int len;
3285
3286     TRACE("(%p %p %d)\n", this, locinfo, isdef);
3287
3288     _Locinfo__Getcvt(locinfo, &cvt);
3289
3290     to_convert = _Locinfo__Getfalse(locinfo);
3291     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3292     this->false_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3293     if(this->false_name)
3294         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3295                 (wchar_t*)this->false_name, len);
3296
3297     to_convert = _Locinfo__Gettrue(locinfo);
3298     len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0);
3299     this->true_name = MSVCRT_operator_new(len*sizeof(WCHAR));
3300     if(this->true_name)
3301         MultiByteToWideChar(cvt.page, 0, to_convert, -1,
3302                 (wchar_t*)this->true_name, len);
3303
3304     if(isdef) {
3305         this->grouping = MSVCRT_operator_new(1);
3306         if(this->grouping)
3307             *(char*)this->grouping = 0;
3308
3309         this->dp = '.';
3310         this->sep = ',';
3311     } else {
3312         const struct lconv *lc = _Locinfo__Getlconv(locinfo);
3313
3314         len = strlen(lc->grouping)+1;
3315         this->grouping = MSVCRT_operator_new(len);
3316         if(this->grouping)
3317             memcpy((char*)this->grouping, lc->grouping, len);
3318
3319         this->dp = lc->decimal_point[0];
3320         this->sep = lc->thousands_sep[0];
3321     }
3322
3323     if(!this->false_name || !this->true_name || !this->grouping) {
3324         MSVCRT_operator_delete((char*)this->grouping);
3325         MSVCRT_operator_delete((wchar_t*)this->false_name);
3326         MSVCRT_operator_delete((wchar_t*)this->true_name);
3327
3328         ERR("Out of memory\n");
3329         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3330     }
3331 }
3332
3333 /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */
3334 /* ?_Tidy@?$numpunct@_W@std@@AEAAXXZ */
3335 /* ?_Tidy@?$numpunct@G@std@@AAEXXZ */
3336 /* ?_Tidy@?$numpunct@G@std@@AEAAXXZ */
3337 static void numpunct_wchar__Tidy(numpunct_wchar *this)
3338 {
3339     TRACE("(%p)\n", this);
3340
3341     MSVCRT_operator_delete((char*)this->grouping);
3342     MSVCRT_operator_delete((wchar_t*)this->false_name);
3343     MSVCRT_operator_delete((wchar_t*)this->true_name);
3344 }
3345
3346 /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */
3347 /* ??0?$numpunct@_W@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3348 static numpunct_wchar* numpunct_wchar_ctor_locinfo(numpunct_wchar *this,
3349         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3350 {
3351     TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef);
3352     locale_facet_ctor_refs(&this->facet, refs);
3353     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3354     numpunct_wchar__Init(this, locinfo, usedef);
3355     return this;
3356 }
3357
3358 /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */
3359 /* ??0?$numpunct@G@std@@QEAA@AEBV_Locinfo@1@_K_N@Z */
3360 static numpunct_wchar* numpunct_short_ctor_locinfo(numpunct_wchar *this,
3361         const _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef)
3362 {
3363     numpunct_wchar_ctor_locinfo(this, locinfo, refs, usedef);
3364     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3365     return this;
3366 }
3367
3368 /* ??0?$numpunct@_W@std@@IAE@PBDI_N@Z */
3369 /* ??0?$numpunct@_W@std@@IEAA@PEBD_K_N@Z */
3370 static numpunct_wchar* numpunct_wchar_ctor_name(numpunct_wchar *this,
3371         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3372 {
3373     _Locinfo locinfo;
3374
3375     TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef);
3376     locale_facet_ctor_refs(&this->facet, refs);
3377     this->facet.vtable = &MSVCP_numpunct_wchar_vtable;
3378
3379     _Locinfo_ctor_cstr(&locinfo, name);
3380     numpunct_wchar__Init(this, &locinfo, usedef);
3381     _Locinfo_dtor(&locinfo);
3382     return this;
3383 }
3384
3385 /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */
3386 /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */
3387 static numpunct_wchar* numpunct_short_ctor_name(numpunct_wchar *this,
3388         const char *name, MSVCP_size_t refs, MSVCP_bool usedef)
3389 {
3390     numpunct_wchar_ctor_name(this, name, refs, usedef);
3391     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3392     return this;
3393 }
3394
3395 /* ??0?$numpunct@_W@std@@QAE@I@Z */
3396 /* ??0?$numpunct@_W@std@@QEAA@_K@Z */
3397 static numpunct_wchar* numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3398 {
3399     TRACE("(%p %lu)\n", this, refs);
3400     return numpunct_wchar_ctor_name(this, "C", refs, FALSE);
3401 }
3402
3403 /* ??0?$numpunct@G@std@@QAE@I@Z */
3404 /* ??0?$numpunct@G@std@@QEAA@_K@Z */
3405 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_refs, 8)
3406 numpunct_wchar* __thiscall numpunct_short_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs)
3407 {
3408     numpunct_wchar_ctor_refs(this, refs);
3409     this->facet.vtable = &MSVCP_numpunct_short_vtable;
3410     return this;
3411 }
3412
3413 /* ??_F?$numpunct@G@std@@QAEXXZ */
3414 /* ??_F?$numpunct@G@std@@QEAAXXZ */
3415 DEFINE_THISCALL_WRAPPER(numpunct_short_ctor, 4)
3416 numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this)
3417 {
3418     return numpunct_short_ctor_refs(this, 0);
3419 }
3420
3421 /* ??1?$numpunct@_W@std@@MAE@XZ */
3422 /* ??1?$numpunct@_W@std@@MEAA@XZ */
3423 /* ??1?$numpunct@G@std@@MAE@XZ */
3424 /* ??1?$numpunct@G@std@@MEAA@XZ */
3425 static void numpunct_wchar_dtor(numpunct_wchar *this)
3426 {
3427     TRACE("(%p)\n", this);
3428     numpunct_wchar__Tidy(this);
3429 }
3430
3431 DEFINE_THISCALL_WRAPPER(numpunct_wchar_vector_dtor, 8)
3432 numpunct_wchar* __thiscall numpunct_wchar_vector_dtor(numpunct_wchar *this, unsigned int flags)
3433 {
3434     TRACE("(%p %x)\n", this, flags);
3435     if(flags & 2) {
3436         /* we have an array, with the number of elements stored before the first object */
3437         INT_PTR i, *ptr = (INT_PTR *)this-1;
3438
3439         for(i=*ptr-1; i>=0; i--)
3440             numpunct_wchar_dtor(this+i);
3441         MSVCRT_operator_delete(ptr);
3442     } else {
3443         numpunct_wchar_dtor(this);
3444         if(flags & 1)
3445             MSVCRT_operator_delete(this);
3446     }
3447
3448     return this;
3449 }
3450
3451 /* ?_Getcat@?$numpunct@_W@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3452 /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3453 static MSVCP_size_t numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc)
3454 {
3455     TRACE("(%p %p)\n", facet, loc);
3456
3457     if(facet && !*facet) {
3458         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3459         if(!*facet) {
3460             ERR("Out of memory\n");
3461             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3462             return 0;
3463         }
3464         numpunct_wchar_ctor_name((numpunct_wchar*)*facet,
3465                 basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3466     }
3467
3468     return LC_NUMERIC;
3469 }
3470
3471 static numpunct_wchar* numpunct_wchar_use_facet(const locale *loc)
3472 {
3473     static numpunct_wchar *obj = NULL;
3474
3475     _Lockit lock;
3476     const locale_facet *fac;
3477
3478     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3479     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_wchar_id));
3480     if(fac) {
3481         _Lockit_dtor(&lock);
3482         return (numpunct_wchar*)fac;
3483     }
3484
3485     if(obj) {
3486         _Lockit_dtor(&lock);
3487         return obj;
3488     }
3489
3490     numpunct_wchar__Getcat(&fac, loc);
3491     obj = (numpunct_wchar*)fac;
3492     locale_facet__Incref(&obj->facet);
3493     locale_facet_register(&obj->facet);
3494     _Lockit_dtor(&lock);
3495
3496     return obj;
3497 }
3498
3499 /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3500 /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3501 static MSVCP_size_t numpunct_short__Getcat(const locale_facet **facet, const locale *loc)
3502 {
3503     TRACE("(%p %p)\n", facet, loc);
3504
3505     if(facet && !*facet) {
3506         *facet = MSVCRT_operator_new(sizeof(numpunct_wchar));
3507         if(!*facet) {
3508             ERR("Out of memory\n");
3509             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3510             return 0;
3511         }
3512         numpunct_short_ctor_name((numpunct_wchar*)*facet,
3513                 basic_string_char_c_str(&loc->ptr->name), 0, TRUE);
3514     }
3515
3516     return LC_NUMERIC;
3517 }
3518
3519 static numpunct_wchar* numpunct_short_use_facet(const locale *loc)
3520 {
3521     static numpunct_wchar *obj = NULL;
3522
3523     _Lockit lock;
3524     const locale_facet *fac;
3525
3526     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3527     fac = locale__Getfacet(loc, locale_id_operator_size_t(&numpunct_short_id));
3528     if(fac) {
3529         _Lockit_dtor(&lock);
3530         return (numpunct_wchar*)fac;
3531     }
3532
3533     if(obj) {
3534         _Lockit_dtor(&lock);
3535         return obj;
3536     }
3537
3538     numpunct_short__Getcat(&fac, loc);
3539     obj = (numpunct_wchar*)fac;
3540     locale_facet__Incref(&obj->facet);
3541     locale_facet_register(&obj->facet);
3542     _Lockit_dtor(&lock);
3543
3544     return obj;
3545 }
3546
3547 /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */
3548 /* ?do_decimal_point@?$numpunct@_W@std@@MEBA_WXZ */
3549 /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */
3550 /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */
3551 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4)
3552 #define call_numpunct_wchar_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \
3553         wchar_t, (const numpunct_wchar *this), (this))
3554 wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this)
3555 {
3556     TRACE("(%p)\n", this);
3557     return this->dp;
3558 }
3559
3560 /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */
3561 /* ?decimal_point@?$numpunct@_W@std@@QEBA_WXZ */
3562 /* ?decimal_point@?$numpunct@G@std@@QBEGXZ */
3563 /* ?decimal_point@?$numpunct@G@std@@QEBAGXZ */
3564 DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4)
3565 wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this)
3566 {
3567     TRACE("(%p)\n", this);
3568     return call_numpunct_wchar_do_decimal_point(this);
3569 }
3570
3571 /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */
3572 /* ?do_thousands_sep@?$numpunct@_W@std@@MEBA_WXZ */
3573 /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */
3574 /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */
3575 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4)
3576 #define call_numpunct_wchar_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \
3577         wchar_t, (const numpunct_wchar *this), (this))
3578 wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this)
3579 {
3580     TRACE("(%p)\n", this);
3581     return this->sep;
3582 }
3583
3584 /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */
3585 /* ?thousands_sep@?$numpunct@_W@std@@QEBA_WXZ */
3586 /* ?thousands_sep@?$numpunct@G@std@@QBEGXZ */
3587 /* ?thousands_sep@?$numpunct@G@std@@QEBAGXZ */
3588 DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4)
3589 wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this)
3590 {
3591     TRACE("(%p)\n", this);
3592     return call_numpunct_wchar_do_thousands_sep(this);
3593 }
3594
3595 /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3596 /* ?do_grouping@?$numpunct@_W@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3597 /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3598 /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3599 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8)
3600 #define call_numpunct_wchar_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \
3601         basic_string_char*, (const numpunct_wchar*, basic_string_char*), (this, ret))
3602 basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret)
3603 {
3604     TRACE("(%p)\n", this);
3605     return basic_string_char_ctor_cstr(ret, this->grouping);
3606 }
3607
3608 /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3609 /* ?grouping@?$numpunct@_W@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3610 /* ?grouping@?$numpunct@G@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3611 /* ?grouping@?$numpunct@G@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
3612 DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8)
3613 basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret)
3614 {
3615     TRACE("(%p)\n", this);
3616     return call_numpunct_wchar_do_grouping(this, ret);
3617 }
3618
3619 /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3620 /* ?do_falsename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3621 /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3622 /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3623 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8)
3624 #define call_numpunct_wchar_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \
3625         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
3626 basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
3627 {
3628     TRACE("(%p)\n", this);
3629     return basic_string_wchar_ctor_cstr(ret, this->false_name);
3630 }
3631
3632 /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3633 /* ?falsename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3634 /* ?falsename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3635 /* ?falsename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3636 DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8)
3637 basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret)
3638 {
3639     TRACE("(%p)\n", this);
3640     return call_numpunct_wchar_do_falsename(this, ret);
3641 }
3642
3643 /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3644 /* ?do_truename@?$numpunct@_W@std@@MEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3645 /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3646 /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3647 DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8)
3648 #define call_numpunct_wchar_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \
3649         basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret))
3650 basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret)
3651 {
3652     TRACE("(%p)\n", this);
3653     return basic_string_wchar_ctor_cstr(ret, this->true_name);
3654 }
3655
3656 /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3657 /* ?truename@?$numpunct@_W@std@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
3658 /* ?truename@?$numpunct@G@std@@QBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3659 /* ?truename@?$numpunct@G@std@@QEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */
3660 DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8)
3661 basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret)
3662 {
3663     TRACE("(%p)\n", this);
3664     return call_numpunct_wchar_do_truename(this, ret);
3665 }
3666
3667 double __cdecl _Stod(const char *buf, char **buf_end, LONG exp)
3668 {
3669     double ret = strtod(buf, buf_end);
3670
3671     if(exp)
3672         ret *= pow(10, exp);
3673     return ret;
3674 }
3675
3676 static double _Stodx(const char *buf, char **buf_end, LONG exp, int *err)
3677 {
3678     double ret;
3679
3680     *err = *_errno();
3681     *_errno() = 0;
3682     ret = _Stod(buf, buf_end, exp);
3683     if(*_errno()) {
3684         *err = *_errno();
3685     }else {
3686         *_errno() = *err;
3687         *err = 0;
3688     }
3689     return ret;
3690 }
3691
3692 float __cdecl _Stof(const char *buf, char **buf_end, LONG exp)
3693 {
3694     return _Stod(buf, buf_end, exp);
3695 }
3696
3697 static float _Stofx(const char *buf, char **buf_end, LONG exp, int *err)
3698 {
3699     return _Stodx(buf, buf_end, exp, err);
3700 }
3701
3702 static __int64 _Stollx(const char *buf, char **buf_end, int base, int *err)
3703 {
3704     __int64 ret;
3705
3706     *err = *_errno();
3707     *_errno() = 0;
3708     ret = _strtoi64(buf, buf_end, base);
3709     if(*_errno()) {
3710         *err = *_errno();
3711     }else {
3712         *_errno() = *err;
3713         *err = 0;
3714     }
3715     return ret;
3716 }
3717
3718 static LONG _Stolx(const char *buf, char **buf_end, int base, int *err)
3719 {
3720     __int64 i = _Stollx(buf, buf_end, base, err);
3721     if(!*err && i!=(__int64)((LONG)i))
3722         *err = ERANGE;
3723     return i;
3724 }
3725
3726 static unsigned __int64 _Stoullx(const char *buf, char **buf_end, int base, int *err)
3727 {
3728     unsigned __int64 ret;
3729
3730     *err = *_errno();
3731     *_errno() = 0;
3732     ret = _strtoui64(buf, buf_end, base);
3733     if(*_errno()) {
3734         *err = *_errno();
3735     }else {
3736         *_errno() = *err;
3737         *err = 0;
3738     }
3739     return ret;
3740 }
3741
3742 static ULONG _Stoulx(const char *buf, char **buf_end, int base, int *err)
3743 {
3744     unsigned __int64 i = _Stoullx(buf[0]=='-' ? buf+1 : buf, buf_end, base, err);
3745     if(!*err && i!=(unsigned __int64)((ULONG)i))
3746         *err = ERANGE;
3747     return buf[0]=='-' ? -i : i;
3748 }
3749
3750 /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
3751 static locale_id num_get_wchar_id = {0};
3752 /* ?id@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
3753 locale_id num_get_short_id = {0};
3754
3755 /* ??_7?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
3756 extern const vtable_ptr MSVCP_num_get_wchar_vtable;
3757 /* ??_7?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
3758 extern const vtable_ptr MSVCP_num_get_short_vtable;
3759
3760 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
3761 /* ?_Init@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
3762 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
3763 /* ?_Init@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
3764 DEFINE_THISCALL_WRAPPER(num_get_wchar__Init, 8)
3765 void __thiscall num_get_wchar__Init(num_get *this, const _Locinfo *locinfo)
3766 {
3767     TRACE("(%p %p)\n", this, locinfo);
3768     _Locinfo__Getcvt(locinfo, &this->cvt);
3769 }
3770
3771 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
3772 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
3773 static num_get* num_get_wchar_ctor_locinfo(num_get *this,
3774         const _Locinfo *locinfo, MSVCP_size_t refs)
3775 {
3776     TRACE("(%p %p %lu)\n", this, locinfo, refs);
3777
3778     locale_facet_ctor_refs(&this->facet, refs);
3779     this->facet.vtable = &MSVCP_num_get_wchar_vtable;
3780
3781     num_get_wchar__Init(this, locinfo);
3782     return this;
3783 }
3784
3785 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
3786 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
3787 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_locinfo, 12)
3788 num_get* __thiscall num_get_short_ctor_locinfo(num_get *this,
3789         const _Locinfo *locinfo, MSVCP_size_t refs)
3790 {
3791     num_get_wchar_ctor_locinfo(this, locinfo, refs);
3792     this->facet.vtable = &MSVCP_num_get_short_vtable;
3793     return this;
3794 }
3795
3796 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
3797 /* ??0?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
3798 static num_get* num_get_wchar_ctor_refs(num_get *this, MSVCP_size_t refs)
3799 {
3800     _Locinfo locinfo;
3801
3802     TRACE("(%p %lu)\n", this, refs);
3803
3804     _Locinfo_ctor(&locinfo);
3805     num_get_wchar_ctor_locinfo(this, &locinfo, refs);
3806     _Locinfo_dtor(&locinfo);
3807     return this;
3808 }
3809
3810 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
3811 /* ??0?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
3812 DEFINE_THISCALL_WRAPPER(num_get_short_ctor_refs, 8)
3813 num_get* __thiscall num_get_short_ctor_refs(num_get *this, MSVCP_size_t refs)
3814 {
3815     num_get_wchar_ctor_refs(this, refs);
3816     this->facet.vtable = &MSVCP_num_get_short_vtable;
3817     return this;
3818 }
3819
3820 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAEXXZ */
3821 /* ??_F?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAAXXZ */
3822 DEFINE_THISCALL_WRAPPER(num_get_short_ctor, 4)
3823 num_get* __thiscall num_get_short_ctor(num_get *this)
3824 {
3825     return num_get_short_ctor_refs(this, 0);
3826 }
3827
3828 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
3829 /* ??1?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
3830 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
3831 /* ??1?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
3832 static void num_get_wchar_dtor(num_get *this)
3833 {
3834     TRACE("(%p)\n", this);
3835     locale_facet_dtor(&this->facet);
3836 }
3837
3838 DEFINE_THISCALL_WRAPPER(num_get_wchar_vector_dtor, 8)
3839 num_get* __thiscall num_get_wchar_vector_dtor(num_get *this, unsigned int flags)
3840 {
3841     TRACE("(%p %x)\n", this, flags);
3842     if(flags & 2) {
3843         /* we have an array, with the number of elements stored before the first object */
3844         INT_PTR i, *ptr = (INT_PTR *)this-1;
3845
3846         for(i=*ptr-1; i>=0; i--)
3847             num_get_wchar_dtor(this+i);
3848         MSVCRT_operator_delete(ptr);
3849     } else {
3850         num_get_wchar_dtor(this);
3851         if(flags & 1)
3852             MSVCRT_operator_delete(this);
3853     }
3854
3855     return this;
3856 }
3857
3858 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3859 /* ?_Getcat@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3860 static MSVCP_size_t num_get_wchar__Getcat(const locale_facet **facet, const locale *loc)
3861 {
3862     TRACE("(%p %p)\n", facet, loc);
3863
3864     if(facet && !*facet) {
3865         _Locinfo locinfo;
3866
3867         *facet = MSVCRT_operator_new(sizeof(num_get));
3868         if(!*facet) {
3869             ERR("Out of memory\n");
3870             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
3871             return 0;
3872         }
3873
3874         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
3875         num_get_wchar_ctor_locinfo((num_get*)*facet, &locinfo, 0);
3876         _Locinfo_dtor(&locinfo);
3877     }
3878
3879     return LC_NUMERIC;
3880 }
3881
3882 static num_get* num_get_wchar_use_facet(const locale *loc)
3883 {
3884         static num_get *obj = NULL;
3885
3886         _Lockit lock;
3887         const locale_facet *fac;
3888
3889         _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3890         fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_wchar_id));
3891         if(fac) {
3892             _Lockit_dtor(&lock);
3893             return (num_get*)fac;
3894         }
3895
3896         if(obj) {
3897             _Lockit_dtor(&lock);
3898             return obj;
3899         }
3900
3901         num_get_wchar__Getcat(&fac, loc);
3902         obj = (num_get*)fac;
3903         locale_facet__Incref(&obj->facet);
3904         locale_facet_register(&obj->facet);
3905         _Lockit_dtor(&lock);
3906
3907         return obj;
3908 }
3909
3910 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
3911 /* ?_Getcat@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
3912 static MSVCP_size_t num_get_short__Getcat(const locale_facet **facet, const locale *loc)
3913 {
3914     if(facet && !*facet) {
3915         num_get_wchar__Getcat(facet, loc);
3916         (*(locale_facet**)facet)->vtable = &MSVCP_num_get_short_vtable;
3917     }
3918
3919     return LC_NUMERIC;
3920 }
3921
3922 num_get* num_get_short_use_facet(const locale *loc)
3923 {
3924     static num_get *obj = NULL;
3925
3926     _Lockit lock;
3927     const locale_facet *fac;
3928
3929     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
3930     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_short_id));
3931     if(fac) {
3932         _Lockit_dtor(&lock);
3933         return (num_get*)fac;
3934     }
3935
3936     if(obj) {
3937         _Lockit_dtor(&lock);
3938         return obj;
3939     }
3940
3941     num_get_short__Getcat(&fac, loc);
3942     obj = (num_get*)fac;
3943     locale_facet__Incref(&obj->facet);
3944     locale_facet_register(&obj->facet);
3945     _Lockit_dtor(&lock);
3946
3947     return obj;
3948 }
3949
3950 static inline wchar_t mb_to_wc(char ch, const _Cvtvec *cvt)
3951 {
3952     int state = 0;
3953     wchar_t ret;
3954
3955     return _Mbrtowc(&ret, &ch, 1, &state, cvt) == 1 ? ret : 0;
3956 }
3957
3958 static int num_get__Getffld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
3959         istreambuf_iterator_wchar *last, const locale *loc, numpunct_wchar *numpunct)
3960 {
3961     basic_string_char grouping_bstr;
3962     basic_string_char groups_found;
3963     int i, groups_no = 0, cur_group = 0, exp = 0;
3964     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31;
3965     wchar_t sep, digits[11], *digits_pos;
3966     const char *grouping, *groups;
3967     BOOL error = FALSE, got_digit = FALSE, got_nonzero = FALSE;
3968
3969     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
3970
3971     for(i=0; i<10; i++)
3972         digits[i] = mb_to_wc('0'+i, &this->cvt);
3973     digits[10] = 0;
3974
3975     numpunct_wchar_grouping(numpunct, &grouping_bstr);
3976     grouping = basic_string_char_c_str(&grouping_bstr);
3977     sep = grouping ? numpunct_wchar_thousands_sep(numpunct) : (wchar_t)0;
3978
3979     if(sep)
3980         basic_string_char_ctor(&groups_found);
3981
3982     istreambuf_iterator_wchar_val(first);
3983     /* get sign */
3984     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
3985         *dest++ = '-';
3986         istreambuf_iterator_wchar_inc(first);
3987     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
3988         *dest++ = '+';
3989         istreambuf_iterator_wchar_inc(first);
3990     }
3991
3992     /* read possibly grouped numbers before decimal */
3993     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
3994         if(!(digits_pos = wcschr(digits, first->val))) {
3995             if(sep && first->val==sep) {
3996                 if(!groups_no) break; /* empty group - stop parsing */
3997                 basic_string_char_append_ch(&groups_found, groups_no);
3998                 groups_no = 0;
3999                 ++cur_group;
4000             }else {
4001                 break;
4002             }
4003         }else {
4004             got_digit = TRUE; /* found a digit, zero or non-zero */
4005             /* write digit to dest if not a leading zero (to not waste dest buffer) */
4006             if(!got_nonzero && first->val == digits[0])
4007             {
4008                 ++groups_no;
4009                 continue;
4010             }
4011             got_nonzero = TRUE;
4012             if(dest < num_end)
4013                 *dest++ = '0'+digits_pos-digits;
4014             else
4015                 exp++; /* too many digits, just multiply by 10 */
4016             if(sep && groups_no<CHAR_MAX)
4017                 ++groups_no;
4018         }
4019     }
4020     /* if all leading zeroes, we didn't write anything so put a zero we check for a decimal */
4021     if(got_digit && !got_nonzero)
4022         *dest++ = '0';
4023
4024     /* get decimal, if any */
4025     if(first->strbuf && first->val==numpunct_wchar_decimal_point(numpunct)) {
4026         if(dest < num_end)
4027             *dest++ = *localeconv()->decimal_point;
4028         istreambuf_iterator_wchar_inc(first);
4029     }
4030
4031     /* read non-grouped after decimal */
4032     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4033         if(!(digits_pos = wcschr(digits, first->val)))
4034             break;
4035         else if(dest<num_end) {
4036             got_digit = TRUE;
4037             *dest++ = '0'+digits_pos-digits;
4038         }
4039     }
4040
4041     /* read exponent, if any */
4042     if(first->strbuf && (first->val==mb_to_wc('e', &this->cvt) || first->val==mb_to_wc('E', &this->cvt))) {
4043         *dest++ = 'e';
4044         istreambuf_iterator_wchar_inc(first);
4045
4046         if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4047             *dest++ = '-';
4048             istreambuf_iterator_wchar_inc(first);
4049         }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4050             *dest++ = '+';
4051             istreambuf_iterator_wchar_inc(first);
4052         }
4053
4054         got_digit = got_nonzero = FALSE;
4055         error = TRUE;
4056         /* skip any leading zeroes */
4057         for(; first->strbuf && first->val==digits[0]; istreambuf_iterator_wchar_inc(first))
4058             error = FALSE;
4059
4060         for(; first->strbuf && (digits_pos = wcschr(digits, first->val)); istreambuf_iterator_wchar_inc(first)) {
4061             got_digit = got_nonzero = TRUE; /* leading zeroes would have been skipped, so first digit is non-zero */
4062             error = FALSE;
4063             if(dest<exp_end)
4064                 *dest++ = '0'+digits_pos-digits;
4065         }
4066
4067         /* if just found zeroes for exponent, use that */
4068         if(got_digit && !got_nonzero)
4069         {
4070             error = FALSE;
4071             if(dest<exp_end)
4072                 *dest++ = '0';
4073         }
4074     }
4075
4076     if(sep && groups_no)
4077         basic_string_char_append_ch(&groups_found, groups_no);
4078
4079     if(!cur_group) /* no groups, skip loop */
4080         cur_group--;
4081     else if(!(groups = basic_string_char_c_str(&groups_found))[cur_group])
4082         error = TRUE; /* trailing empty */
4083
4084     for(; cur_group>=0 && !error; cur_group--) {
4085         if(*grouping == CHAR_MAX) {
4086             if(cur_group)
4087                 error = TRUE;
4088             break;
4089         }else if((cur_group && *grouping!=groups[cur_group])
4090                 || (!cur_group && *grouping<groups[cur_group])) {
4091             error = TRUE;
4092             break;
4093         }else if(grouping[1]) {
4094             grouping++;
4095         }
4096     }
4097     basic_string_char_dtor(&grouping_bstr);
4098     if(sep)
4099         basic_string_char_dtor(&groups_found);
4100
4101     if(error) {
4102         *dest_beg = '\0';
4103         return 0;
4104     }
4105     *dest++ = '\0';
4106     return exp;
4107 }
4108
4109 static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4110     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc, numpunct_wchar *numpunct)
4111 {
4112     wchar_t digits[23], *digits_pos, sep;
4113     basic_string_char grouping_bstr;
4114     basic_string_char groups_found;
4115     int i, basefield, base, groups_no = 0, cur_group = 0;
4116     char *dest_beg = dest, *dest_end = dest+24;
4117     const char *grouping, *groups;
4118     BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
4119
4120     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
4121
4122     for(i=0; i<10; i++)
4123         digits[i] = mb_to_wc('0'+i, &this->cvt);
4124     for(i=0; i<6; i++) {
4125         digits[10+i] = mb_to_wc('a'+i, &this->cvt);
4126         digits[16+i] = mb_to_wc('A'+i, &this->cvt);
4127     }
4128
4129     numpunct_wchar_grouping(numpunct, &grouping_bstr);
4130     grouping = basic_string_char_c_str(&grouping_bstr);
4131     sep = grouping ? numpunct_wchar_thousands_sep(numpunct) : '\0';
4132
4133     basefield = fmtflags & FMTFLAG_basefield;
4134     if(basefield == FMTFLAG_oct)
4135         base = 8;
4136     else if(basefield == FMTFLAG_hex)
4137         base = 22; /* equal to the size of digits buffer */
4138     else if(!basefield)
4139         base = 0;
4140     else
4141         base = 10;
4142
4143     istreambuf_iterator_wchar_val(first);
4144     if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
4145         *dest++ = '-';
4146         istreambuf_iterator_wchar_inc(first);
4147     }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
4148         *dest++ = '+';
4149         istreambuf_iterator_wchar_inc(first);
4150     }
4151
4152     if(first->strbuf && first->val==digits[0]) {
4153         found_zero = TRUE;
4154         istreambuf_iterator_wchar_inc(first);
4155         if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('X', &this->cvt))) {
4156             if(!base || base == 22) {
4157                 found_zero = FALSE;
4158                 istreambuf_iterator_wchar_inc(first);
4159                 base = 22;
4160             }else {
4161                 base = 10;
4162             }
4163         }else {
4164             error = FALSE;
4165             if(!base) base = 8;
4166         }
4167     }else {
4168         if(!base) base = 10;
4169     }
4170     digits[base] = 0;
4171
4172     if(sep) {
4173         basic_string_char_ctor(&groups_found);
4174         if(found_zero) ++groups_no;
4175     }
4176
4177     for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
4178         if(!(digits_pos = wcschr(digits, first->val))) {
4179             if(sep && first->val==sep) {
4180                 if(!groups_no) break; /* empty group - stop parsing */
4181                 basic_string_char_append_ch(&groups_found, groups_no);
4182                 groups_no = 0;
4183                 ++cur_group;
4184             }else {
4185                 break;
4186             }
4187         }else {
4188             error = FALSE;
4189             if(dest_empty && first->val == digits[0]) {
4190                 found_zero = TRUE;
4191                 ++groups_no;
4192                 continue;
4193             }
4194             dest_empty = FALSE;
4195             /* skip digits that can't be copied to dest buffer, other
4196              * functions are responsible for detecting overflows */
4197             if(dest < dest_end)
4198                 *dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
4199                         (digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
4200                          'A'+digits_pos-digits-16));
4201             if(sep && groups_no<CHAR_MAX)
4202                 ++groups_no;
4203         }
4204     }
4205
4206     if(sep && groups_no)
4207         basic_string_char_append_ch(&groups_found, groups_no);
4208
4209     if(!cur_group) { /* no groups, skip loop */
4210         cur_group--;
4211     }else if(!(groups = basic_string_char_c_str(&groups_found))[cur_group]) {
4212         error = TRUE; /* trailing empty */
4213         found_zero = FALSE;
4214     }
4215
4216     for(; cur_group>=0 && !error; cur_group--) {
4217         if(*grouping == CHAR_MAX) {
4218             if(cur_group)
4219                 error = TRUE;
4220             break;
4221         }else if((cur_group && *grouping!=groups[cur_group])
4222                 || (!cur_group && *grouping<groups[cur_group])) {
4223             error = TRUE;
4224             break;
4225         }else if(grouping[1]) {
4226             grouping++;
4227         }
4228     }
4229
4230     basic_string_char_dtor(&grouping_bstr);
4231     if(sep)
4232         basic_string_char_dtor(&groups_found);
4233
4234     if(error) {
4235         if (found_zero)
4236             *dest++ = '0';
4237         else
4238             dest = dest_beg;
4239     }else if(dest_empty)
4240         *dest++ = '0';
4241     *dest = '\0';
4242
4243     return (base==22 ? 16 : base);
4244 }
4245
4246 /* ?_Getifld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1HABVlocale@2@@Z */
4247 /* ?_Getifld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1HAEBVlocale@2@@Z */
4248 static int num_get_wchar__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
4249     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
4250 {
4251     return num_get__Getifld(this, dest, first, last,
4252             fmtflags, loc, numpunct_wchar_use_facet(loc));
4253 }
4254
4255 static istreambuf_iterator_wchar* num_get_do_get_void(const num_get *this,
4256         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4257         istreambuf_iterator_wchar last, ios_base *base, int *state,
4258         void **pval, numpunct_wchar *numpunct)
4259 {
4260     unsigned __int64 v;
4261     char tmp[25], *end;
4262     int err;
4263
4264     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4265
4266     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4267                 &last, FMTFLAG_hex, base->loc, numpunct), &err);
4268     if(v!=(unsigned __int64)((INT_PTR)v))
4269         *state |= IOSTATE_failbit;
4270     else if(end!=tmp && !err)
4271         *pval = (void*)((INT_PTR)v);
4272     else
4273         *state |= IOSTATE_failbit;
4274
4275     if(!first.strbuf)
4276         *state |= IOSTATE_eofbit;
4277
4278     *ret = first;
4279     return ret;
4280 }
4281
4282 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4283 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4284 #define call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_wchar*, \
4285         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, void**), \
4286         (this, ret, first, last, base, state, pval))
4287 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_void,36)
4288 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4289     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4290 {
4291     return num_get_do_get_void(this, ret, first, last, base,
4292             state, pval, numpunct_wchar_use_facet(base->loc));
4293 }
4294
4295 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4296 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4297 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_void,36)
4298 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4299     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4300 {
4301     return num_get_do_get_void(this, ret, first, last, base,
4302             state, pval, numpunct_short_use_facet(base->loc));
4303 }
4304
4305 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4306 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4307 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
4308 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
4309 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_void,36)
4310 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_void(const num_get *this, istreambuf_iterator_wchar *ret,
4311     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, void **pval)
4312 {
4313     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4314     return call_num_get_wchar_do_get_void(this, ret, first, last, base, state, pval);
4315 }
4316
4317 static istreambuf_iterator_wchar* num_get_do_get_double(const num_get *this,
4318         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4319         istreambuf_iterator_wchar last, ios_base *base, int *state,
4320         double *pval, numpunct_wchar *numpunct)
4321 {
4322     double v;
4323     char tmp[32], *end;
4324     int err;
4325
4326     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4327
4328     v = _Stodx(tmp, &end, num_get__Getffld(this, tmp, &first, &last, base->loc, numpunct), &err);
4329     if(end!=tmp && !err)
4330         *pval = v;
4331     else
4332         *state |= IOSTATE_failbit;
4333
4334     if(!first.strbuf)
4335         *state |= IOSTATE_eofbit;
4336
4337     *ret = first;
4338     return ret;
4339 }
4340
4341 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4342 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4343 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4344 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4345 #define call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_wchar*, \
4346         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4347         (this, ret, first, last, base, state, pval))
4348 #define call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_wchar*, \
4349         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, double*), \
4350         (this, ret, first, last, base, state, pval))
4351 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_double,36)
4352 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4353     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4354 {
4355     return num_get_do_get_double(this, ret, first, last, base,
4356             state, pval, numpunct_wchar_use_facet(base->loc));
4357 }
4358
4359 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4360 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4361 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4362 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4363 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_double,36)
4364 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4365     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4366 {
4367     return num_get_do_get_double(this, ret, first, last, base,
4368             state, pval, numpunct_short_use_facet(base->loc));
4369 }
4370
4371 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4372 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4373 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
4374 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
4375 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ldouble,36)
4376 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ldouble(const num_get *this, istreambuf_iterator_wchar *ret,
4377         istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4378 {
4379     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4380     return call_num_get_wchar_do_get_ldouble(this, ret, first, last, base, state, pval);
4381 }
4382
4383 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4384 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4385 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
4386 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
4387 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_double,36)
4388 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_double(const num_get *this, istreambuf_iterator_wchar *ret,
4389     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, double *pval)
4390 {
4391     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4392     return call_num_get_wchar_do_get_double(this, ret, first, last, base, state, pval);
4393 }
4394
4395 static istreambuf_iterator_wchar* num_get_do_get_float(const num_get *this,
4396         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4397         istreambuf_iterator_wchar last, ios_base *base, int *state,
4398         float *pval, numpunct_wchar *numpunct)
4399 {
4400     float v;
4401     char tmp[32], *end;
4402     int err;
4403
4404     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4405
4406     v = _Stofx(tmp, &end, num_get__Getffld(this, tmp, &first,
4407                 &last, base->loc, numpunct), &err);
4408     if(end!=tmp && !err)
4409         *pval = v;
4410     else
4411         *state |= IOSTATE_failbit;
4412
4413     if(!first.strbuf)
4414         *state |= IOSTATE_eofbit;
4415
4416     *ret = first;
4417     return ret;
4418 }
4419
4420 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4421 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4422 #define call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_wchar*, \
4423         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, float*), \
4424         (this, ret, first, last, base, state, pval))
4425 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_float,36)
4426 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4427     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4428 {
4429     return num_get_do_get_float(this, ret, first, last, base,
4430             state, pval, numpunct_wchar_use_facet(base->loc));
4431 }
4432
4433 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4434 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4435 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_float,36)
4436 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4437     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4438 {
4439     return num_get_do_get_float(this, ret, first, last, base,
4440             state, pval, numpunct_short_use_facet(base->loc));
4441 }
4442
4443 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4444 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4445 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
4446 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
4447 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_float,36)
4448 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_float(const num_get *this, istreambuf_iterator_wchar *ret,
4449     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, float *pval)
4450 {
4451     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4452     return call_num_get_wchar_do_get_float(this, ret, first, last, base, state, pval);
4453 }
4454
4455 static istreambuf_iterator_wchar* num_get_do_get_uint64(const num_get *this,
4456         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4457         istreambuf_iterator_wchar last, ios_base *base, int *state,
4458         ULONGLONG *pval, numpunct_wchar *numpunct)
4459 {
4460     unsigned __int64 v;
4461     char tmp[25], *end;
4462     int err;
4463
4464     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4465
4466     v = _Stoullx(tmp, &end, num_get__Getifld(this, tmp, &first,
4467                 &last, base->fmtfl, base->loc, numpunct), &err);
4468     if(end!=tmp && !err)
4469         *pval = v;
4470     else
4471         *state |= IOSTATE_failbit;
4472
4473     if(!first.strbuf)
4474         *state |= IOSTATE_eofbit;
4475
4476     *ret = first;
4477     return ret;
4478 }
4479
4480 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4481 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4482 #define call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_wchar*, \
4483         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONGLONG*), \
4484         (this, ret, first, last, base, state, pval))
4485 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint64,36)
4486 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4487     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4488 {
4489     return num_get_do_get_uint64(this, ret, first, last, base,
4490             state, pval, numpunct_wchar_use_facet(base->loc));
4491 }
4492
4493 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4494 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4495 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint64,36)
4496 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4497     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4498 {
4499     return num_get_do_get_uint64(this, ret, first, last, base,
4500             state, pval, numpunct_short_use_facet(base->loc));
4501 }
4502
4503 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4504 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4505 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
4506 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
4507 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint64,36)
4508 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint64(const num_get *this, istreambuf_iterator_wchar *ret,
4509     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONGLONG *pval)
4510 {
4511     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4512     return call_num_get_wchar_do_get_uint64(this, ret, first, last, base, state, pval);
4513 }
4514
4515 static istreambuf_iterator_wchar* num_get_do_get_int64(const num_get *this,
4516         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4517         istreambuf_iterator_wchar last, ios_base *base, int *state,
4518         LONGLONG *pval, numpunct_wchar *numpunct)
4519 {
4520     __int64 v;
4521     char tmp[25], *end;
4522     int err;
4523
4524     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4525
4526     v = _Stollx(tmp, &end, num_get__Getifld(this, tmp, &first,
4527                 &last, base->fmtfl, base->loc, numpunct), &err);
4528     if(end!=tmp && !err)
4529         *pval = v;
4530     else
4531         *state |= IOSTATE_failbit;
4532
4533     if(!first.strbuf)
4534         *state |= IOSTATE_eofbit;
4535
4536     *ret = first;
4537     return ret;
4538 }
4539
4540 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
4541 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
4542 #define call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_wchar*, \
4543         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONGLONG*), \
4544         (this, ret, first, last, base, state, pval))
4545 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_int64,36)
4546 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
4547     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
4548 {
4549     return num_get_do_get_int64(this, ret, first, last, base,
4550             state, pval, numpunct_wchar_use_facet(base->loc));
4551 }
4552
4553 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
4554 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
4555 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_int64,36)
4556 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
4557     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
4558 {
4559     return num_get_do_get_int64(this, ret, first, last, base,
4560             state, pval, numpunct_short_use_facet(base->loc));
4561 }
4562
4563 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
4564 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
4565 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
4566 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
4567 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_int64,36)
4568 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_int64(const num_get *this, istreambuf_iterator_wchar *ret,
4569     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONGLONG *pval)
4570 {
4571     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4572     return call_num_get_wchar_do_get_int64(this, ret, first, last, base, state, pval);
4573 }
4574
4575 static istreambuf_iterator_wchar* num_get_do_get_ulong(const num_get *this,
4576         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4577         istreambuf_iterator_wchar last, ios_base *base, int *state,
4578         ULONG *pval, numpunct_wchar *numpunct)
4579 {
4580     ULONG v;
4581     char tmp[25], *end;
4582     int err;
4583
4584     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4585
4586     v = _Stoulx(tmp, &end, num_get__Getifld(this, tmp, &first,
4587                 &last, base->fmtfl, base->loc, numpunct), &err);
4588     if(end!=tmp && !err)
4589         *pval = v;
4590     else
4591         *state |= IOSTATE_failbit;
4592
4593     if(!first.strbuf)
4594         *state |= IOSTATE_eofbit;
4595
4596     *ret = first;
4597     return ret;
4598 }
4599
4600 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
4601 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
4602 #define call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_wchar*, \
4603         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, ULONG*), \
4604         (this, ret, first, last, base, state, pval))
4605 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ulong,36)
4606 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
4607     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
4608 {
4609     return num_get_do_get_ulong(this, ret, first, last, base,
4610             state, pval, numpunct_wchar_use_facet(base->loc));
4611 }
4612
4613 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
4614 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
4615 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ulong,36)
4616 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
4617     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
4618 {
4619     return num_get_do_get_ulong(this, ret, first, last, base,
4620             state, pval, numpunct_short_use_facet(base->loc));
4621 }
4622
4623 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
4624 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
4625 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
4626 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
4627 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ulong,36)
4628 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ulong(const num_get *this, istreambuf_iterator_wchar *ret,
4629     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, ULONG *pval)
4630 {
4631     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4632     return call_num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
4633 }
4634
4635 static istreambuf_iterator_wchar* num_get_do_get_long(const num_get *this,
4636         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4637         istreambuf_iterator_wchar last, ios_base *base, int *state,
4638         LONG *pval, numpunct_wchar *numpunct)
4639 {
4640     LONG v;
4641     char tmp[25], *end;
4642     int err;
4643
4644     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4645
4646     v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
4647                 &last, base->fmtfl, base->loc, numpunct), &err);
4648     if(end!=tmp && !err)
4649         *pval = v;
4650     else
4651         *state |= IOSTATE_failbit;
4652
4653     if(!first.strbuf)
4654         *state |= IOSTATE_eofbit;
4655
4656     *ret = first;
4657     return ret;
4658 }
4659
4660 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
4661 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
4662 #define call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_wchar*, \
4663         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, LONG*), \
4664         (this, ret, first, last, base, state, pval))
4665 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_long,36)
4666 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
4667     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
4668 {
4669     return num_get_do_get_long(this, ret, first, last, base,
4670             state, pval, numpunct_wchar_use_facet(base->loc));
4671 }
4672
4673 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
4674 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
4675 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_long,36)
4676 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
4677     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
4678 {
4679     return num_get_do_get_long(this, ret, first, last, base,
4680         state, pval, numpunct_short_use_facet(base->loc));
4681 }
4682
4683 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
4684 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
4685 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
4686 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
4687 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_long,36)
4688 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_long(const num_get *this, istreambuf_iterator_wchar *ret,
4689     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, LONG *pval)
4690 {
4691     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4692     return call_num_get_wchar_do_get_long(this, ret, first, last, base, state, pval);
4693 }
4694
4695 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
4696 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
4697 #define call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_wchar*, \
4698         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned int*), \
4699         (this, ret, first, last, base, state, pval))
4700 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_uint,36)
4701 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
4702     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
4703 {
4704     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4705     return num_get_wchar_do_get_ulong(this, ret, first, last, base, state, pval);
4706 }
4707
4708 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
4709 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
4710 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_uint,36)
4711 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
4712     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
4713 {
4714     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4715     return num_get_short_do_get_ulong(this, ret, first, last, base, state, pval);
4716 }
4717
4718 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
4719 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
4720 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
4721 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
4722 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_uint,36)
4723 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_uint(const num_get *this, istreambuf_iterator_wchar *ret,
4724     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned int *pval)
4725 {
4726     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4727     return call_num_get_wchar_do_get_uint(this, ret, first, last, base, state, pval);
4728 }
4729
4730 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
4731 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
4732 #define call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_wchar*, \
4733         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, unsigned short*), \
4734         (this, ret, first, last, base, state, pval))
4735 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_ushort,36)
4736 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
4737     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
4738 {
4739     ULONG v;
4740     char tmp[25], *beg, *end;
4741     int err, b;
4742
4743     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4744
4745     b = num_get_wchar__Getifld(this, tmp,
4746             &first, &last, base->fmtfl, base->loc);
4747     beg = tmp + (tmp[0]=='-' ? 1 : 0);
4748     v = _Stoulx(beg, &end, b, &err);
4749
4750     if(v != (ULONG)((unsigned short)v))
4751         *state |= IOSTATE_failbit;
4752     else if(end!=beg && !err)
4753         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
4754     else
4755         *state |= IOSTATE_failbit;
4756
4757     if(!first.strbuf)
4758         *state |= IOSTATE_eofbit;
4759
4760     *ret = first;
4761     return ret;
4762 }
4763
4764 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
4765 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
4766 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_ushort,36)
4767 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
4768     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
4769 {
4770     FIXME("(%p %p %p %p %p) stub\n", this, ret, base, state, pval);
4771     return ret;
4772 }
4773
4774 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
4775 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
4776 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAAG@ */
4777 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
4778 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_ushort,36)
4779 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_ushort(const num_get *this, istreambuf_iterator_wchar *ret,
4780     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, unsigned short *pval)
4781 {
4782     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4783     return call_num_get_wchar_do_get_ushort(this, ret, first, last, base, state, pval);
4784 }
4785
4786 static istreambuf_iterator_wchar* num_get_do_get_bool(const num_get *this,
4787         istreambuf_iterator_wchar *ret, istreambuf_iterator_wchar first,
4788         istreambuf_iterator_wchar last, ios_base *base, int *state,
4789         MSVCP_bool *pval, numpunct_wchar *numpunct)
4790 {
4791     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4792
4793     if(base->fmtfl & FMTFLAG_boolalpha) {
4794         basic_string_wchar false_bstr, true_bstr;
4795         const wchar_t *pfalse, *ptrue;
4796
4797         numpunct_wchar_falsename(numpunct, &false_bstr);
4798         numpunct_wchar_truename(numpunct, &true_bstr);
4799         pfalse = basic_string_wchar_c_str(&false_bstr);
4800         ptrue = basic_string_wchar_c_str(&true_bstr);
4801
4802         for(istreambuf_iterator_wchar_val(&first); first.strbuf;
4803                 istreambuf_iterator_wchar_inc(&first)) {
4804             if(pfalse && *pfalse && first.val!=*pfalse)
4805                 pfalse = NULL;
4806             if(ptrue && *ptrue && first.val!=*ptrue)
4807                 ptrue = NULL;
4808
4809             if(pfalse && *pfalse && ptrue && !*ptrue)
4810                 ptrue = NULL;
4811             if(ptrue && *ptrue && pfalse && !*pfalse)
4812                 pfalse = NULL;
4813
4814             if(pfalse)
4815                 pfalse++;
4816             if(ptrue)
4817                 ptrue++;
4818
4819             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
4820                 break;
4821         }
4822
4823         if(ptrue)
4824             *pval = TRUE;
4825         else if(pfalse)
4826             *pval = FALSE;
4827         else
4828             *state |= IOSTATE_failbit;
4829
4830         basic_string_wchar_dtor(&false_bstr);
4831         basic_string_wchar_dtor(&true_bstr);
4832     }else {
4833         char tmp[25], *end;
4834         int err;
4835         LONG v = _Stolx(tmp, &end, num_get__Getifld(this, tmp, &first,
4836                     &last, base->fmtfl, base->loc, numpunct), &err);
4837
4838         if(end!=tmp && err==0 && (v==0 || v==1))
4839             *pval = v;
4840         else
4841             *state |= IOSTATE_failbit;
4842     }
4843
4844     if(!first.strbuf)
4845         *state |= IOSTATE_eofbit;
4846     memcpy(ret, &first, sizeof(first));
4847     return ret;
4848 }
4849
4850 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
4851 /* ?do_get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
4852 #define call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_wchar*, \
4853         (const num_get*, istreambuf_iterator_wchar*, istreambuf_iterator_wchar, istreambuf_iterator_wchar, ios_base*, int*, MSVCP_bool*), \
4854         (this, ret, first, last, base, state, pval))
4855 DEFINE_THISCALL_WRAPPER(num_get_wchar_do_get_bool,36)
4856 istreambuf_iterator_wchar *__thiscall num_get_wchar_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
4857     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
4858 {
4859     return num_get_do_get_bool(this, ret, first, last, base,
4860             state, pval, numpunct_wchar_use_facet(base->loc));
4861 }
4862
4863 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
4864 /* ?do_get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
4865 DEFINE_THISCALL_WRAPPER(num_get_short_do_get_bool,36)
4866 istreambuf_iterator_wchar *__thiscall num_get_short_do_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
4867     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
4868 {
4869     return num_get_do_get_bool(this, ret, first, last, base,
4870             state, pval, numpunct_short_use_facet(base->loc));
4871 }
4872
4873 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
4874 /* ?get@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
4875 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
4876 /* ?get@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
4877 DEFINE_THISCALL_WRAPPER(num_get_wchar_get_bool,36)
4878 istreambuf_iterator_wchar *__thiscall num_get_wchar_get_bool(const num_get *this, istreambuf_iterator_wchar *ret,
4879     istreambuf_iterator_wchar first, istreambuf_iterator_wchar last, ios_base *base, int *state, MSVCP_bool *pval)
4880 {
4881     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
4882     return call_num_get_wchar_do_get_bool(this, ret, first, last, base, state, pval);
4883 }
4884
4885 /* ?id@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
4886 locale_id num_get_char_id = {0};
4887
4888 /* ??_7?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
4889 extern const vtable_ptr MSVCP_num_get_char_vtable;
4890
4891 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
4892 /* ?_Init@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
4893 DEFINE_THISCALL_WRAPPER(num_get_char__Init, 8)
4894 void __thiscall num_get_char__Init(num_get *this, const _Locinfo *locinfo)
4895 {
4896     TRACE("(%p %p)\n", this, locinfo);
4897     _Locinfo__Getcvt(locinfo, &this->cvt);
4898 }
4899
4900 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
4901 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
4902 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_locinfo, 12)
4903 num_get* __thiscall num_get_char_ctor_locinfo(num_get *this,
4904         const _Locinfo *locinfo, MSVCP_size_t refs)
4905 {
4906     TRACE("(%p %p %lu)\n", this, locinfo, refs);
4907
4908     locale_facet_ctor_refs(&this->facet, refs);
4909     this->facet.vtable = &MSVCP_num_get_char_vtable;
4910
4911     num_get_char__Init(this, locinfo);
4912     return this;
4913 }
4914
4915 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
4916 /* ??0?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
4917 DEFINE_THISCALL_WRAPPER(num_get_char_ctor_refs, 8)
4918 num_get* __thiscall num_get_char_ctor_refs(num_get *this, MSVCP_size_t refs)
4919 {
4920     _Locinfo locinfo;
4921
4922     TRACE("(%p %lu)\n", this, refs);
4923
4924     _Locinfo_ctor(&locinfo);
4925     num_get_char_ctor_locinfo(this, &locinfo, refs);
4926     _Locinfo_dtor(&locinfo);
4927     return this;
4928 }
4929
4930 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
4931 /* ??_F?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
4932 DEFINE_THISCALL_WRAPPER(num_get_char_ctor, 4)
4933 num_get* __thiscall num_get_char_ctor(num_get *this)
4934 {
4935     return num_get_char_ctor_refs(this, 0);
4936 }
4937
4938 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
4939 /* ??1?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
4940 static void num_get_char_dtor(num_get *this)
4941 {
4942     TRACE("(%p)\n", this);
4943     locale_facet_dtor(&this->facet);
4944 }
4945
4946 DEFINE_THISCALL_WRAPPER(num_get_char_vector_dtor, 8)
4947 num_get* __thiscall num_get_char_vector_dtor(num_get *this, unsigned int flags)
4948 {
4949     TRACE("(%p %x)\n", this, flags);
4950     if(flags & 2) {
4951         /* we have an array, with the number of elements stored before the first object */
4952         INT_PTR i, *ptr = (INT_PTR *)this-1;
4953
4954         for(i=*ptr-1; i>=0; i--)
4955             num_get_char_dtor(this+i);
4956         MSVCRT_operator_delete(ptr);
4957     } else {
4958         num_get_char_dtor(this);
4959         if(flags & 1)
4960             MSVCRT_operator_delete(this);
4961     }
4962
4963     return this;
4964 }
4965
4966 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
4967 /* ?_Getcat@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
4968 static MSVCP_size_t num_get_char__Getcat(const locale_facet **facet, const locale *loc)
4969 {
4970     TRACE("(%p %p)\n", facet, loc);
4971
4972     if(facet && !*facet) {
4973         _Locinfo locinfo;
4974
4975         *facet = MSVCRT_operator_new(sizeof(num_get));
4976         if(!*facet) {
4977             ERR("Out of memory\n");
4978             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
4979             return 0;
4980         }
4981
4982         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
4983         num_get_char_ctor_locinfo((num_get*)*facet, &locinfo, 0);
4984         _Locinfo_dtor(&locinfo);
4985     }
4986
4987     return LC_NUMERIC;
4988 }
4989
4990 num_get* num_get_char_use_facet(const locale *loc)
4991 {
4992     static num_get *obj = NULL;
4993
4994     _Lockit lock;
4995     const locale_facet *fac;
4996
4997     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
4998     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_get_char_id));
4999     if(fac) {
5000         _Lockit_dtor(&lock);
5001         return (num_get*)fac;
5002     }
5003
5004     if(obj) {
5005         _Lockit_dtor(&lock);
5006         return obj;
5007     }
5008
5009     num_get_char__Getcat(&fac, loc);
5010     obj = (num_get*)fac;
5011     locale_facet__Incref(&obj->facet);
5012     locale_facet_register(&obj->facet);
5013     _Lockit_dtor(&lock);
5014
5015     return obj;
5016 }
5017
5018 /* ?_Getffld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1ABVlocale@2@@Z */
5019 /* ?_Getffld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1AEBVlocale@2@@Z */
5020 /* Copies number to dest buffer, validates grouping and skips separators.
5021  * Updates first so it points past the number, all digits are skipped.
5022  * Returns how exponent needs to changed.
5023  * Size of dest buffer is not specified, assuming it's not smaller than 32:
5024  * strlen(+0.e+) + 22(digits) + 4(expontent) + 1(nullbyte)
5025  */
5026 static int num_get_char__Getffld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5027         istreambuf_iterator_char *last, const locale *loc)
5028 {
5029     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5030     basic_string_char grouping_bstr;
5031     basic_string_char groups_found;
5032     int groups_no = 0, cur_group = 0, exp = 0;
5033     char *dest_beg = dest, *num_end = dest+25, *exp_end = dest+31, sep;
5034     const char *grouping, *groups;
5035     BOOL error = FALSE, got_digit = FALSE, got_nonzero = FALSE;
5036
5037     TRACE("(%p %p %p %p)\n", dest, first, last, loc);
5038
5039     numpunct_char_grouping(numpunct, &grouping_bstr);
5040     grouping = basic_string_char_c_str(&grouping_bstr);
5041     sep = grouping ? numpunct_char_thousands_sep(numpunct) : '\0';
5042
5043     if(sep)
5044         basic_string_char_ctor(&groups_found);
5045
5046     istreambuf_iterator_char_val(first);
5047     /* get sign */
5048     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5049         *dest++ = first->val;
5050         istreambuf_iterator_char_inc(first);
5051     }
5052
5053
5054     /* read possibly grouped numbers before decimal */
5055     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5056         if(first->val<'0' || first->val>'9') {
5057             if(sep && first->val==sep) {
5058                 if(!groups_no) break; /* empty group - stop parsing */
5059                 basic_string_char_append_ch(&groups_found, groups_no);
5060                 groups_no = 0;
5061                 ++cur_group;
5062             }else {
5063                 break;
5064             }
5065         }else {
5066             got_digit = TRUE; /* found a digit, zero or non-zero */
5067             /* write digit to dest if not a leading zero (to not waste dest buffer) */
5068             if(!got_nonzero && first->val == '0')
5069             {
5070                 ++groups_no;
5071                 continue;
5072             }
5073             got_nonzero = TRUE;
5074             if(dest < num_end)
5075                 *dest++ = first->val;
5076             else
5077                 exp++; /* too many digits, just multiply by 10 */
5078             if(sep && groups_no<CHAR_MAX)
5079                 ++groups_no;
5080         }
5081     }
5082     /* if all leading zeroes, we didn't write anything so put a zero we check for a decimal */
5083     if(got_digit && !got_nonzero)
5084         *dest++ = '0';
5085
5086     /* get decimal, if any */
5087     if(first->strbuf && first->val==numpunct_char_decimal_point(numpunct)) {
5088         if(dest < num_end)
5089             *dest++ = *localeconv()->decimal_point;
5090         istreambuf_iterator_char_inc(first);
5091     }
5092
5093     /* read non-grouped after decimal */
5094     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5095         if(first->val<'0' || first->val>'9')
5096             break;
5097         else if(dest<num_end) {
5098             got_digit = TRUE;
5099             *dest++ = first->val;
5100         }
5101     }
5102
5103     /* read exponent, if any */
5104     if(first->strbuf && (first->val=='e' || first->val=='E')) {
5105         *dest++ = first->val;
5106         istreambuf_iterator_char_inc(first);
5107
5108         if(first->strbuf && (first->val=='-' || first->val=='+')) {
5109             *dest++ = first->val;
5110             istreambuf_iterator_char_inc(first);
5111         }
5112
5113         got_digit = got_nonzero = FALSE;
5114         error = TRUE;
5115         /* skip any leading zeroes */
5116         for(; first->strbuf && first->val=='0'; istreambuf_iterator_char_inc(first))
5117             got_digit = TRUE;
5118
5119         for(; first->strbuf && first->val>='0' && first->val<='9'; istreambuf_iterator_char_inc(first)) {
5120             got_digit = got_nonzero = TRUE; /* leading zeroes would have been skipped, so first digit is non-zero */
5121             error = FALSE;
5122             if(dest<exp_end)
5123                 *dest++ = first->val;
5124         }
5125
5126         /* if just found zeroes for exponent, use that */
5127         if(got_digit && !got_nonzero)
5128         {
5129             error = FALSE;
5130             if(dest<exp_end)
5131                 *dest++ = '0';
5132         }
5133     }
5134
5135     if(sep && groups_no)
5136         basic_string_char_append_ch(&groups_found, groups_no);
5137
5138     if(!cur_group) /* no groups, skip loop */
5139         cur_group--;
5140     else if(!(groups = basic_string_char_c_str(&groups_found))[cur_group])
5141         error = TRUE; /* trailing empty */
5142
5143     for(; cur_group>=0 && !error; cur_group--) {
5144         if(*grouping == CHAR_MAX) {
5145             if(cur_group)
5146                 error = TRUE;
5147             break;
5148         }else if((cur_group && *grouping!=groups[cur_group])
5149                 || (!cur_group && *grouping<groups[cur_group])) {
5150             error = TRUE;
5151             break;
5152         }else if(grouping[1]) {
5153             grouping++;
5154         }
5155     }
5156     basic_string_char_dtor(&grouping_bstr);
5157     if(sep)
5158         basic_string_char_dtor(&groups_found);
5159
5160     if(error) {
5161         *dest_beg = '\0';
5162         return 0;
5163     }
5164     *dest++ = '\0';
5165     return exp;
5166 }
5167
5168 /* ?_Getifld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1HABVlocale@2@@Z */
5169 /* ?_Getifld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@1HAEBVlocale@2@@Z */
5170 /* Copies number to dest buffer, validates grouping and skips separators.
5171  * Updates first so it points past the number, all digits are skipped.
5172  * Returns number base (8, 10 or 16).
5173  * Size of dest buffer is not specified, assuming it's not smaller than 25:
5174  * 22(8^22>2^64)+1(detect overflows)+1(sign)+1(nullbyte) = 25
5175  */
5176 static int num_get_char__Getifld(const num_get *this, char *dest, istreambuf_iterator_char *first,
5177         istreambuf_iterator_char *last, int fmtflags, const locale *loc)
5178 {
5179     static const char digits[] = "0123456789abcdefABCDEF";
5180
5181     numpunct_char *numpunct = numpunct_char_use_facet(loc);
5182     basic_string_char grouping_bstr;
5183     basic_string_char groups_found;
5184     int basefield, base, groups_no = 0, cur_group = 0;
5185     char *dest_beg = dest, *dest_end = dest+24, sep;
5186     const char *grouping, *groups;
5187     BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
5188
5189     TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
5190
5191     numpunct_char_grouping(numpunct, &grouping_bstr);
5192     grouping = basic_string_char_c_str(&grouping_bstr);
5193     sep = grouping ? numpunct_char_thousands_sep(numpunct) : '\0';
5194
5195     basefield = fmtflags & FMTFLAG_basefield;
5196     if(basefield == FMTFLAG_oct)
5197         base = 8;
5198     else if(basefield == FMTFLAG_hex)
5199         base = 22; /* equal to the size of digits buffer */
5200     else if(!basefield)
5201         base = 0;
5202     else
5203         base = 10;
5204
5205     istreambuf_iterator_char_val(first);
5206     if(first->strbuf && (first->val=='-' || first->val=='+')) {
5207         *dest++ = first->val;
5208         istreambuf_iterator_char_inc(first);
5209     }
5210
5211     if(first->strbuf && first->val=='0') {
5212         found_zero = TRUE;
5213         istreambuf_iterator_char_inc(first);
5214         if(first->strbuf && (first->val=='x' || first->val=='X')) {
5215             if(!base || base == 22) {
5216                 found_zero = FALSE;
5217                 istreambuf_iterator_char_inc(first);
5218                 base = 22;
5219             }else {
5220                 base = 10;
5221             }
5222         }else {
5223             error = FALSE;
5224             if(!base) base = 8;
5225         }
5226     }else {
5227         if (!base) base = 10;
5228     }
5229
5230     if(sep)
5231     {
5232         basic_string_char_ctor(&groups_found);
5233         if(found_zero) ++groups_no;
5234     }
5235
5236     for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
5237         if(!memchr(digits, first->val, base)) {
5238             if(sep && first->val==sep) {
5239                 if(!groups_no) break; /* empty group - stop parsing */
5240                 basic_string_char_append_ch(&groups_found, groups_no);
5241                 groups_no = 0;
5242                 ++cur_group;
5243             }else {
5244                 break;
5245             }
5246         }else {
5247             error = FALSE;
5248             if(dest_empty && first->val == '0')
5249             {
5250                 found_zero = TRUE;
5251                 ++groups_no;
5252                 continue;
5253             }
5254             dest_empty = FALSE;
5255             /* skip digits that can't be copied to dest buffer, other
5256              * functions are responsible for detecting overflows */
5257             if(dest < dest_end)
5258                 *dest++ = first->val;
5259             if(sep && groups_no<CHAR_MAX)
5260                 ++groups_no;
5261         }
5262     }
5263
5264     if(sep && groups_no)
5265         basic_string_char_append_ch(&groups_found, groups_no);
5266
5267     if(!cur_group) { /* no groups, skip loop */
5268         cur_group--;
5269     }else if(!(groups = basic_string_char_c_str(&groups_found))[cur_group]) {
5270         error = TRUE; /* trailing empty */
5271         found_zero = FALSE;
5272     }
5273
5274     for(; cur_group>=0 && !error; cur_group--) {
5275         if(*grouping == CHAR_MAX) {
5276             if(cur_group)
5277                 error = TRUE;
5278             break;
5279         }else if((cur_group && *grouping!=groups[cur_group])
5280                 || (!cur_group && *grouping<groups[cur_group])) {
5281             error = TRUE;
5282             break;
5283         }else if(grouping[1]) {
5284             grouping++;
5285         }
5286     }
5287
5288     basic_string_char_dtor(&grouping_bstr);
5289     if(sep)
5290         basic_string_char_dtor(&groups_found);
5291
5292     if(error) {
5293         if (found_zero)
5294             *dest++ = '0';
5295         else
5296             dest = dest_beg;
5297     }else if(dest_empty)
5298         *dest++ = '0';
5299     *dest = '\0';
5300
5301     return (base==22 ? 16 : base);
5302 }
5303
5304 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
5305 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
5306 #define call_num_get_char_do_get_void(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 4, istreambuf_iterator_char*, \
5307         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, void**), \
5308         (this, ret, first, last, base, state, pval))
5309 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_void,36)
5310 istreambuf_iterator_char *__thiscall num_get_char_do_get_void(const num_get *this, istreambuf_iterator_char *ret,
5311     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5312 {
5313     unsigned __int64 v;
5314     char tmp[25], *end;
5315     int err;
5316
5317     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5318
5319     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5320                 &first, &last, FMTFLAG_hex, base->loc), &err);
5321     if(v!=(unsigned __int64)((INT_PTR)v))
5322         *state |= IOSTATE_failbit;
5323     else if(end!=tmp && !err)
5324         *pval = (void*)((INT_PTR)v);
5325     else
5326         *state |= IOSTATE_failbit;
5327
5328     if(!first.strbuf)
5329         *state |= IOSTATE_eofbit;
5330
5331     *ret = first;
5332     return ret;
5333 }
5334
5335 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAPAX@Z */
5336 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAPEAX@Z */
5337 DEFINE_THISCALL_WRAPPER(num_get_char_get_void,36)
5338 istreambuf_iterator_char *__thiscall num_get_char_get_void(const num_get *this, istreambuf_iterator_char *ret,
5339     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, void **pval)
5340 {
5341     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5342     return call_num_get_char_do_get_void(this, ret, first, last, base, state, pval);
5343 }
5344
5345 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
5346 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
5347 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
5348 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
5349 #define call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 8, istreambuf_iterator_char*, \
5350         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5351         (this, ret, first, last, base, state, pval))
5352 #define call_num_get_char_do_get_double(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 12, istreambuf_iterator_char*, \
5353         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, double*), \
5354         (this, ret, first, last, base, state, pval))
5355 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_double,36)
5356 istreambuf_iterator_char *__thiscall num_get_char_do_get_double(const num_get *this, istreambuf_iterator_char *ret,
5357     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5358 {
5359     double v;
5360     char tmp[32], *end;
5361     int err;
5362
5363     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5364
5365     v = _Stodx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5366     if(end!=tmp && !err)
5367         *pval = v;
5368     else
5369         *state |= IOSTATE_failbit;
5370
5371     if(!first.strbuf)
5372         *state |= IOSTATE_eofbit;
5373
5374     *ret = first;
5375     return ret;
5376 }
5377
5378 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAO@Z */
5379 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAO@Z */
5380 DEFINE_THISCALL_WRAPPER(num_get_char_get_ldouble,36)
5381 istreambuf_iterator_char *__thiscall num_get_char_get_ldouble(const num_get *this, istreambuf_iterator_char *ret,
5382         istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5383 {
5384     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5385     return call_num_get_char_do_get_ldouble(this, ret, first, last, base, state, pval);
5386 }
5387
5388 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAN@Z */
5389 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAN@Z */
5390 DEFINE_THISCALL_WRAPPER(num_get_char_get_double,36)
5391 istreambuf_iterator_char *__thiscall num_get_char_get_double(const num_get *this, istreambuf_iterator_char *ret,
5392     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, double *pval)
5393 {
5394     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5395     return call_num_get_char_do_get_double(this, ret, first, last, base, state, pval);
5396 }
5397
5398 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
5399 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
5400 #define call_num_get_char_do_get_float(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 16, istreambuf_iterator_char*, \
5401         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, float*), \
5402         (this, ret, first, last, base, state, pval))
5403 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_float,36)
5404 istreambuf_iterator_char *__thiscall num_get_char_do_get_float(const num_get *this, istreambuf_iterator_char *ret,
5405     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5406 {
5407     float v;
5408     char tmp[32], *end;
5409     int err;
5410
5411     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5412
5413     v = _Stofx(tmp, &end, num_get_char__Getffld(this, tmp, &first, &last, base->loc), &err);
5414     if(end!=tmp && !err)
5415         *pval = v;
5416     else
5417         *state |= IOSTATE_failbit;
5418
5419     if(!first.strbuf)
5420         *state |= IOSTATE_eofbit;
5421
5422     *ret = first;
5423     return ret;
5424 }
5425
5426 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z */
5427 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAM@Z */
5428 DEFINE_THISCALL_WRAPPER(num_get_char_get_float,36)
5429 istreambuf_iterator_char *__thiscall num_get_char_get_float(const num_get *this, istreambuf_iterator_char *ret,
5430     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, float *pval)
5431 {
5432     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5433     return call_num_get_char_do_get_float(this, ret, first, last, base, state, pval);
5434 }
5435
5436 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5437 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5438 #define call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 20, istreambuf_iterator_char*, \
5439         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONGLONG*), \
5440         (this, ret, first, last, base, state, pval))
5441 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint64,36)
5442 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5443     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5444 {
5445     unsigned __int64 v;
5446     char tmp[25], *end;
5447     int err;
5448
5449     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5450
5451     v = _Stoullx(tmp, &end, num_get_char__Getifld(this, tmp,
5452                 &first, &last, base->fmtfl, base->loc), &err);
5453     if(end!=tmp && !err)
5454         *pval = v;
5455     else
5456         *state |= IOSTATE_failbit;
5457
5458     if(!first.strbuf)
5459         *state |= IOSTATE_eofbit;
5460
5461     *ret = first;
5462     return ret;
5463 }
5464
5465 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_K@Z */
5466 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_K@Z */
5467 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint64,36)
5468 istreambuf_iterator_char *__thiscall num_get_char_get_uint64(const num_get *this, istreambuf_iterator_char *ret,
5469     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONGLONG *pval)
5470 {
5471     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5472     return call_num_get_char_do_get_uint64(this, ret, first, last, base, state, pval);
5473 }
5474
5475 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5476 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5477 #define call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 24, istreambuf_iterator_char*, \
5478         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONGLONG*), \
5479         (this, ret, first, last, base, state, pval))
5480 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_int64,36)
5481 istreambuf_iterator_char *__thiscall num_get_char_do_get_int64(const num_get *this, istreambuf_iterator_char *ret,
5482     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
5483 {
5484     __int64 v;
5485     char tmp[25], *end;
5486     int err;
5487
5488     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5489
5490     v = _Stollx(tmp, &end, num_get_char__Getifld(this, tmp,
5491                 &first, &last, base->fmtfl, base->loc), &err);
5492     if(end!=tmp && !err)
5493         *pval = v;
5494     else
5495         *state |= IOSTATE_failbit;
5496
5497     if(!first.strbuf)
5498         *state |= IOSTATE_eofbit;
5499
5500     *ret = first;
5501     return ret;
5502 }
5503
5504 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_J@Z */
5505 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_J@Z */
5506 DEFINE_THISCALL_WRAPPER(num_get_char_get_int64,36)
5507 istreambuf_iterator_char *__thiscall num_get_char_get_int64(const num_get *this, istreambuf_iterator_char *ret,
5508     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONGLONG *pval)
5509 {
5510     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5511     return call_num_get_char_do_get_int64(this, ret, first, last, base, state, pval);
5512 }
5513
5514 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5515 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5516 #define call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 28, istreambuf_iterator_char*, \
5517         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, ULONG*), \
5518         (this, ret, first, last, base, state, pval))
5519 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ulong,36)
5520 istreambuf_iterator_char *__thiscall num_get_char_do_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
5521     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
5522 {
5523     ULONG v;
5524     char tmp[25], *end;
5525     int err;
5526
5527     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5528
5529     v = _Stoulx(tmp, &end, num_get_char__Getifld(this, tmp,
5530                 &first, &last, base->fmtfl, base->loc), &err);
5531     if(end!=tmp && !err)
5532         *pval = v;
5533     else
5534         *state |= IOSTATE_failbit;
5535
5536     if(!first.strbuf)
5537         *state |= IOSTATE_eofbit;
5538
5539     *ret = first;
5540     return ret;
5541 }
5542
5543 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z */
5544 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAK@Z */
5545 DEFINE_THISCALL_WRAPPER(num_get_char_get_ulong,36)
5546 istreambuf_iterator_char *__thiscall num_get_char_get_ulong(const num_get *this, istreambuf_iterator_char *ret,
5547     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, ULONG *pval)
5548 {
5549     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5550     return call_num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
5551 }
5552
5553 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5554 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5555 #define call_num_get_char_do_get_long(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 32, istreambuf_iterator_char*, \
5556         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, LONG*), \
5557         (this, ret, first, last, base, state, pval))
5558 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_long,36)
5559 istreambuf_iterator_char *__thiscall num_get_char_do_get_long(const num_get *this, istreambuf_iterator_char *ret,
5560     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
5561 {
5562     LONG v;
5563     char tmp[25], *end;
5564     int err;
5565
5566     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5567
5568     v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
5569                 &first, &last, base->fmtfl, base->loc), &err);
5570     if(end!=tmp && !err)
5571         *pval = v;
5572     else
5573         *state |= IOSTATE_failbit;
5574
5575     if(!first.strbuf)
5576         *state |= IOSTATE_eofbit;
5577
5578     *ret = first;
5579     return ret;
5580 }
5581
5582 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z */
5583 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAJ@Z */
5584 DEFINE_THISCALL_WRAPPER(num_get_char_get_long,36)
5585 istreambuf_iterator_char *__thiscall num_get_char_get_long(const num_get *this, istreambuf_iterator_char *ret,
5586     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, LONG *pval)
5587 {
5588     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5589     return call_num_get_char_do_get_long(this, ret, first, last, base, state, pval);
5590 }
5591
5592 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5593 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5594 #define call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 36, istreambuf_iterator_char*, \
5595         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned int*), \
5596         (this, ret, first, last, base, state, pval))
5597 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_uint,36)
5598 istreambuf_iterator_char *__thiscall num_get_char_do_get_uint(const num_get *this, istreambuf_iterator_char *ret,
5599     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
5600 {
5601     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5602     return num_get_char_do_get_ulong(this, ret, first, last, base, state, pval);
5603 }
5604
5605 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAI@Z */
5606 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAI@Z */
5607 DEFINE_THISCALL_WRAPPER(num_get_char_get_uint,36)
5608 istreambuf_iterator_char *__thiscall num_get_char_get_uint(const num_get *this, istreambuf_iterator_char *ret,
5609     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned int *pval)
5610 {
5611     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5612     return call_num_get_char_do_get_uint(this, ret, first, last, base, state, pval);
5613 }
5614
5615 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
5616 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5617 #define call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 40, istreambuf_iterator_char*, \
5618         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, unsigned short*), \
5619         (this, ret, first, last, base, state, pval))
5620 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_ushort,36)
5621 istreambuf_iterator_char *__thiscall num_get_char_do_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
5622     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
5623 {
5624     ULONG v;
5625     char tmp[25], *beg, *end;
5626     int err, b;
5627
5628     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5629
5630     b = num_get_char__Getifld(this, tmp,
5631             &first, &last, base->fmtfl, base->loc);
5632     beg = tmp + (tmp[0]=='-' ? 1 : 0);
5633     v = _Stoulx(beg, &end, b, &err);
5634
5635     if(v != (ULONG)((unsigned short)v))
5636         *state |= IOSTATE_failbit;
5637     else if(end!=beg && !err)
5638         *pval = (tmp[0]=='-' ? -((unsigned short)v) : v);
5639     else
5640         *state |= IOSTATE_failbit;
5641
5642     if(!first.strbuf)
5643         *state |= IOSTATE_eofbit;
5644
5645     *ret = first;
5646     return ret;
5647 }
5648
5649 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAG@Z */
5650 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEAG@Z */
5651 DEFINE_THISCALL_WRAPPER(num_get_char_get_ushort,36)
5652 istreambuf_iterator_char *__thiscall num_get_char_get_ushort(const num_get *this, istreambuf_iterator_char *ret,
5653     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, unsigned short *pval)
5654 {
5655     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5656     return call_num_get_char_do_get_ushort(this, ret, first, last, base, state, pval);
5657 }
5658
5659 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5660 /* ?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5661 #define call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval) CALL_VTBL_FUNC(this, 44, istreambuf_iterator_char*, \
5662         (const num_get*, istreambuf_iterator_char*, istreambuf_iterator_char, istreambuf_iterator_char, ios_base*, int*, MSVCP_bool*), \
5663         (this, ret, first, last, base, state, pval))
5664 DEFINE_THISCALL_WRAPPER(num_get_char_do_get_bool,36)
5665 istreambuf_iterator_char *__thiscall num_get_char_do_get_bool(const num_get *this, istreambuf_iterator_char *ret,
5666     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
5667 {
5668     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5669
5670     if(base->fmtfl & FMTFLAG_boolalpha) {
5671         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
5672         basic_string_char false_bstr, true_bstr;
5673         const char *pfalse, *ptrue;
5674
5675         numpunct_char_falsename(numpunct, &false_bstr);
5676         numpunct_char_truename(numpunct, &true_bstr);
5677         pfalse = basic_string_char_c_str(&false_bstr);
5678         ptrue = basic_string_char_c_str(&true_bstr);
5679
5680         for(istreambuf_iterator_char_val(&first); first.strbuf;
5681                 istreambuf_iterator_char_inc(&first)) {
5682             if(pfalse && *pfalse && first.val!=*pfalse)
5683                 pfalse = NULL;
5684             if(ptrue && *ptrue && first.val!=*ptrue)
5685                 ptrue = NULL;
5686
5687             if(pfalse && *pfalse && ptrue && !*ptrue)
5688                 ptrue = NULL;
5689             if(ptrue && *ptrue && pfalse && !*pfalse)
5690                 pfalse = NULL;
5691
5692             if(pfalse)
5693                 pfalse++;
5694             if(ptrue)
5695                 ptrue++;
5696
5697             if((!pfalse || !*pfalse) && (!ptrue || !*ptrue))
5698                 break;
5699         }
5700
5701         if(ptrue)
5702             *pval = TRUE;
5703         else if(pfalse)
5704             *pval = FALSE;
5705         else
5706             *state |= IOSTATE_failbit;
5707
5708         basic_string_char_dtor(&false_bstr);
5709         basic_string_char_dtor(&true_bstr);
5710     }else {
5711         char tmp[25], *end;
5712         int err;
5713         LONG v = _Stolx(tmp, &end, num_get_char__Getifld(this, tmp,
5714                     &first, &last, base->fmtfl, base->loc), &err);
5715
5716         if(end!=tmp && err==0 && (v==0 || v==1))
5717             *pval = v;
5718         else
5719             *state |= IOSTATE_failbit;
5720     }
5721
5722     if(!first.strbuf)
5723         *state |= IOSTATE_eofbit;
5724     memcpy(ret, &first, sizeof(first));
5725     return ret;
5726 }
5727
5728 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAA_N@Z */
5729 /* ?get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AEAVios_base@2@AEAHAEA_N@Z */
5730 DEFINE_THISCALL_WRAPPER(num_get_char_get_bool,36)
5731 istreambuf_iterator_char *__thiscall num_get_char_get_bool(const num_get *this, istreambuf_iterator_char *ret,
5732     istreambuf_iterator_char first, istreambuf_iterator_char last, ios_base *base, int *state, MSVCP_bool *pval)
5733 {
5734     TRACE("(%p %p %p %p %p)\n", this, ret, base, state, pval);
5735     return call_num_get_char_do_get_bool(this, ret, first, last, base, state, pval);
5736 }
5737
5738 /* ?id@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@2V0locale@2@A */
5739 locale_id num_put_char_id = {0};
5740
5741 /* num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@6B@ */
5742 extern const vtable_ptr MSVCP_num_put_char_vtable;
5743
5744 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
5745 /* ?_Init@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
5746 DEFINE_THISCALL_WRAPPER(num_put_char__Init, 8)
5747 void __thiscall num_put_char__Init(num_put *this, const _Locinfo *locinfo)
5748 {
5749     TRACE("(%p %p)\n", this, locinfo);
5750     _Locinfo__Getcvt(locinfo, &this->cvt);
5751 }
5752
5753 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
5754 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
5755 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_locinfo, 12)
5756 num_put* __thiscall num_put_char_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
5757 {
5758     TRACE("(%p %p %ld)\n", this, locinfo, refs);
5759
5760     locale_facet_ctor_refs(&this->facet, refs);
5761     this->facet.vtable = &MSVCP_num_put_char_vtable;
5762
5763     num_put_char__Init(this, locinfo);
5764     return this;
5765 }
5766
5767 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAE@I@Z */
5768 /* ??0?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAA@_K@Z */
5769 DEFINE_THISCALL_WRAPPER(num_put_char_ctor_refs, 8)
5770 num_put* __thiscall num_put_char_ctor_refs(num_put *this, MSVCP_size_t refs)
5771 {
5772      _Locinfo locinfo;
5773
5774      TRACE("(%p %lu)\n", this, refs);
5775
5776      _Locinfo_ctor(&locinfo);
5777      num_put_char_ctor_locinfo(this, &locinfo, refs);
5778      _Locinfo_dtor(&locinfo);
5779      return this;
5780 }
5781
5782 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QAEXXZ */
5783 /* ??_F?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEAAXXZ */
5784 DEFINE_THISCALL_WRAPPER(num_put_char_ctor, 4)
5785 num_put* __thiscall num_put_char_ctor(num_put *this)
5786 {
5787     return num_put_char_ctor_refs(this, 0);
5788 }
5789
5790 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MAE@XZ */
5791 /* ??1?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEAA@XZ */
5792 static void num_put_char_dtor(num_put *this)
5793 {
5794     TRACE("(%p)\n", this);
5795     locale_facet_dtor(&this->facet);
5796 }
5797
5798 DEFINE_THISCALL_WRAPPER(num_put_char_vector_dtor, 8)
5799 num_put* __thiscall num_put_char_vector_dtor(num_put *this, unsigned int flags)
5800 {
5801     TRACE("(%p %x)\n", this, flags);
5802     if(flags & 2) {
5803         /* we have an array, with the number of elements stored before the first object */
5804         INT_PTR i, *ptr = (INT_PTR *)this-1;
5805
5806         for(i=*ptr-1; i>=0; i--)
5807             num_put_char_dtor(this+i);
5808         MSVCRT_operator_delete(ptr);
5809     } else {
5810         num_put_char_dtor(this);
5811         if(flags & 1)
5812             MSVCRT_operator_delete(this);
5813     }
5814
5815     return this;
5816 }
5817
5818 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
5819 /* ?_Getcat@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
5820 static MSVCP_size_t num_put_char__Getcat(const locale_facet **facet, const locale *loc)
5821 {
5822     TRACE("(%p %p)\n", facet, loc);
5823
5824     if(facet && !*facet) {
5825         _Locinfo locinfo;
5826
5827         *facet = MSVCRT_operator_new(sizeof(num_put));
5828         if(!*facet) {
5829             ERR("Out of memory\n");
5830             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
5831             return 0;
5832         }
5833
5834         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
5835         num_put_char_ctor_locinfo((num_put*)*facet, &locinfo, 0);
5836         _Locinfo_dtor(&locinfo);
5837     }
5838
5839     return LC_NUMERIC;
5840 }
5841
5842 num_put* num_put_char_use_facet(const locale *loc)
5843 {
5844     static num_put *obj = NULL;
5845
5846     _Lockit lock;
5847     const locale_facet *fac;
5848
5849     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
5850     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_char_id));
5851     if(fac) {
5852         _Lockit_dtor(&lock);
5853         return (num_put*)fac;
5854     }
5855
5856     if(obj) {
5857         _Lockit_dtor(&lock);
5858         return obj;
5859     }
5860
5861     num_put_char__Getcat(&fac, loc);
5862     obj = (num_put*)fac;
5863     locale_facet__Incref(&obj->facet);
5864     locale_facet_register(&obj->facet);
5865     _Lockit_dtor(&lock);
5866
5867     return obj;
5868 }
5869
5870 /* ?_Putc@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PBDI@Z */
5871 /* ?_Putc@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@PEBD_K@Z */
5872 static ostreambuf_iterator_char* num_put_char__Putc(const num_put *this, ostreambuf_iterator_char *ret,
5873         ostreambuf_iterator_char dest, const char *ptr, MSVCP_size_t count)
5874 {
5875     TRACE("(%p %p %p %ld)\n", this, ret, ptr, count);
5876
5877     for(; count>0; count--)
5878         ostreambuf_iterator_char_put(&dest, *ptr++);
5879
5880     *ret = dest;
5881     return ret;
5882 }
5883
5884 /* ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@DI@Z */
5885 /* ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@D_K@Z */
5886 static ostreambuf_iterator_char* num_put_char__Rep(const num_put *this, ostreambuf_iterator_char *ret,
5887         ostreambuf_iterator_char dest, char c, MSVCP_size_t count)
5888 {
5889     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
5890
5891     for(; count>0; count--)
5892         ostreambuf_iterator_char_put(&dest, c);
5893
5894     *ret = dest;
5895     return ret;
5896 }
5897
5898 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADDH@Z */
5899 /* ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADDH@Z */
5900 static char* num_put_char__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
5901 {
5902     int type = fmtfl & FMTFLAG_floatfield;
5903     char *p = fmt;
5904
5905     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
5906
5907     *p++ = '%';
5908     if(fmtfl & FMTFLAG_showpos)
5909         *p++ = '+';
5910     if(fmtfl & FMTFLAG_showbase)
5911         *p++ = '#';
5912     *p++ = '.';
5913     *p++ = '*';
5914     if(spec)
5915         *p++ = spec;
5916
5917     if(type == FMTFLAG_fixed)
5918         *p++ = 'f';
5919     else if(type == FMTFLAG_scientific)
5920         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
5921     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
5922         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
5923     else
5924         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
5925
5926     *p++ = '\0';
5927     return fmt;
5928 }
5929
5930 /* TODO: This function should be removed when num_put_char__Fput is implemented */
5931 static ostreambuf_iterator_char* num_put_char_fput(const num_put *this, ostreambuf_iterator_char *ret,
5932         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
5933 {
5934     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
5935     basic_string_char grouping_bstr;
5936     const char *grouping;
5937     char *p, sep = *localeconv()->decimal_point;
5938     int cur_group = 0, group_size = 0;
5939     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
5940     MSVCP_size_t pad;
5941
5942     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
5943
5944     /* Change decimal point */
5945     for(p=buf; p<buf+count; p++) {
5946         if(*p == sep) {
5947             *p = numpunct_char_decimal_point(numpunct);
5948             break;
5949         }
5950     }
5951     p--;
5952
5953     /* Add separators to number */
5954     numpunct_char_grouping(numpunct, &grouping_bstr);
5955     grouping = basic_string_char_c_str(&grouping_bstr);
5956     sep = grouping ? numpunct_char_thousands_sep(numpunct) : '\0';
5957
5958     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
5959         group_size++;
5960         if(group_size == grouping[cur_group]) {
5961             group_size = 0;
5962             if(grouping[cur_group+1])
5963                 cur_group++;
5964
5965             memmove(p+1, p, buf+count-p);
5966             *p = sep;
5967             count++;
5968         }
5969     }
5970     basic_string_char_dtor(&grouping_bstr);
5971
5972     /* Display number with padding */
5973     if(count >= base->wide)
5974         pad = 0;
5975     else
5976         pad = base->wide-count;
5977     base->wide = 0;
5978
5979     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
5980         num_put_char__Putc(this, &dest, dest, buf, 1);
5981         buf++;
5982     }
5983     if(adjustfield != FMTFLAG_left) {
5984         num_put_char__Rep(this, ret, dest, fill, pad);
5985         pad = 0;
5986     }
5987     num_put_char__Putc(this, &dest, dest, buf, count);
5988     return num_put_char__Rep(this, ret, dest, fill, pad);
5989 }
5990
5991 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADPBDH@Z */
5992 /* ?_Ifmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
5993 static char* num_put_char__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
5994 {
5995     int base = fmtfl & FMTFLAG_basefield;
5996     char *p = fmt;
5997
5998     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
5999
6000     *p++ = '%';
6001     if(fmtfl & FMTFLAG_showpos)
6002         *p++ = '+';
6003     if(fmtfl & FMTFLAG_showbase)
6004         *p++ = '#';
6005
6006     *p++ = *spec++;
6007     if(*spec == 'l')
6008         *p++ = *spec++;
6009
6010     if(base == FMTFLAG_oct)
6011         *p++ = 'o';
6012     else if(base == FMTFLAG_hex)
6013         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
6014     else
6015         *p++ = *spec;
6016
6017     *p++ = '\0';
6018     return fmt;
6019 }
6020
6021 /* ?_Iput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPADI@Z */
6022 /* ?_Iput@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEAD_K@Z */
6023 static ostreambuf_iterator_char* num_put_char__Iput(const num_put *this, ostreambuf_iterator_char *ret,
6024         ostreambuf_iterator_char dest, ios_base *base, char fill, char *buf, MSVCP_size_t count)
6025 {
6026     numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6027     basic_string_char grouping_bstr;
6028     const char *grouping;
6029     char *p, sep;
6030     int cur_group = 0, group_size = 0;
6031     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6032     MSVCP_size_t pad;
6033
6034     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6035
6036     /* Add separators to number */
6037     numpunct_char_grouping(numpunct, &grouping_bstr);
6038     grouping = basic_string_char_c_str(&grouping_bstr);
6039     sep = grouping ? numpunct_char_thousands_sep(numpunct) : '\0';
6040
6041     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6042         group_size++;
6043         if(group_size == grouping[cur_group]) {
6044             group_size = 0;
6045             if(grouping[cur_group+1])
6046                 cur_group++;
6047
6048             memmove(p+1, p, buf+count-p);
6049             *p = sep;
6050             count++;
6051         }
6052     }
6053     basic_string_char_dtor(&grouping_bstr);
6054
6055     /* Display number with padding */
6056     if(count >= base->wide)
6057         pad = 0;
6058     else
6059         pad = base->wide-count;
6060     base->wide = 0;
6061
6062     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6063         num_put_char__Putc(this, &dest, dest, buf, 1);
6064         buf++;
6065     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
6066         num_put_char__Putc(this, &dest, dest, buf, 2);
6067         buf += 2;
6068     }
6069     if(adjustfield != FMTFLAG_left) {
6070         num_put_char__Rep(this, ret, dest, fill, pad);
6071         pad = 0;
6072     }
6073     num_put_char__Putc(this, &dest, dest, buf, count);
6074     return num_put_char__Rep(this, ret, dest, fill, pad);
6075 }
6076
6077 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DJ@Z */
6078 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DJ@Z */
6079 #define call_num_put_char_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_char*, \
6080         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, LONG), \
6081         (this, ret, dest, base, fill, v))
6082 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_long, 28)
6083 ostreambuf_iterator_char* __thiscall num_put_char_do_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6084         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6085 {
6086     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6087     char fmt[7]; /* strlen("%+#lld")+1 */
6088
6089     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6090
6091     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6092             sprintf(tmp, num_put_char__Ifmt(this, fmt, "ld", base->fmtfl), v));
6093 }
6094
6095 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DJ@Z */
6096 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DJ@Z */
6097 DEFINE_THISCALL_WRAPPER(num_put_char_put_long, 28)
6098 ostreambuf_iterator_char* __thiscall num_put_char_put_long(const num_put *this, ostreambuf_iterator_char *ret,
6099         ostreambuf_iterator_char dest, ios_base *base, char fill, LONG v)
6100 {
6101     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6102     return call_num_put_char_do_put_long(this, ret, dest, base, fill, v);
6103 }
6104
6105 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DK@Z */
6106 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DK@Z */
6107 #define call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_char*, \
6108         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, ULONG), \
6109         (this, ret, dest, base, fill, v))
6110 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ulong, 28)
6111 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6112         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6113 {
6114     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6115     char fmt[7]; /* strlen("%+#lld")+1 */
6116
6117     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6118
6119     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6120             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lu", base->fmtfl), v));
6121 }
6122
6123 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DK@Z */
6124 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DK@Z */
6125 DEFINE_THISCALL_WRAPPER(num_put_char_put_ulong, 28)
6126 ostreambuf_iterator_char* __thiscall num_put_char_put_ulong(const num_put *this, ostreambuf_iterator_char *ret,
6127         ostreambuf_iterator_char dest, ios_base *base, char fill, ULONG v)
6128 {
6129     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6130     return call_num_put_char_do_put_ulong(this, ret, dest, base, fill, v);
6131 }
6132
6133 static inline streamsize get_precision(const ios_base *base)
6134 {
6135     return base->prec <= 0 && !(base->fmtfl & FMTFLAG_fixed) ? 6 : base->prec;
6136 }
6137
6138 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DN@Z */
6139 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DN@Z */
6140 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DO@Z */
6141 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DO@Z */
6142 #define call_num_put_char_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_char*, \
6143         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6144         (this, ret, dest, base, fill, v))
6145 #define call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_char*, \
6146         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, double), \
6147         (this, ret, dest, base, fill, v))
6148 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_double, 32)
6149 ostreambuf_iterator_char* __thiscall num_put_char_do_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6150         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6151 {
6152     char *tmp;
6153     char fmt[8]; /* strlen("%+#.*lg")+1 */
6154     int size;
6155     streamsize prec;
6156
6157     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6158
6159     num_put_char__Ffmt(this, fmt, '\0', base->fmtfl);
6160     prec = get_precision(base);
6161     size = _scprintf(fmt, prec, v);
6162
6163     /* TODO: don't use dynamic allocation */
6164     tmp = MSVCRT_operator_new(size*2);
6165     if(!tmp) {
6166         ERR("Out of memory\n");
6167         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6168     }
6169     num_put_char_fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, prec, v));
6170     MSVCRT_operator_delete(tmp);
6171     return ret;
6172 }
6173
6174 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DN@Z */
6175 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DN@Z */
6176 DEFINE_THISCALL_WRAPPER(num_put_char_put_double, 32)
6177 ostreambuf_iterator_char* __thiscall num_put_char_put_double(const num_put *this, ostreambuf_iterator_char *ret,
6178         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6179 {
6180     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6181     return call_num_put_char_do_put_double(this, ret, dest, base, fill, v);
6182 }
6183
6184 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DO@Z */
6185 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DO@Z */
6186 DEFINE_THISCALL_WRAPPER(num_put_char_put_ldouble, 32)
6187 ostreambuf_iterator_char* __thiscall num_put_char_put_ldouble(const num_put *this, ostreambuf_iterator_char *ret,
6188         ostreambuf_iterator_char dest, ios_base *base, char fill, double v)
6189 {
6190     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6191     return call_num_put_char_do_put_ldouble(this, ret, dest, base, fill, v);
6192 }
6193
6194 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPBX@Z */
6195 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEBX@Z */
6196 #define call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_char*, \
6197         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, const void*), \
6198         (this, ret, dest, base, fill, v))
6199 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_ptr, 28)
6200 ostreambuf_iterator_char* __thiscall num_put_char_do_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6201         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6202 {
6203     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
6204
6205     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6206
6207     return num_put_char__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
6208 }
6209
6210 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@DPBX@Z */
6211 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@DPEBX@Z */
6212 DEFINE_THISCALL_WRAPPER(num_put_char_put_ptr, 28)
6213 ostreambuf_iterator_char* __thiscall num_put_char_put_ptr(const num_put *this, ostreambuf_iterator_char *ret,
6214         ostreambuf_iterator_char dest, ios_base *base, char fill, const void *v)
6215 {
6216     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6217     return call_num_put_char_do_put_ptr(this, ret, dest, base, fill, v);
6218 }
6219
6220 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_J@Z */
6221 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_J@Z */
6222 #define call_num_put_char_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_char*, \
6223         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, __int64), \
6224         (this, ret, dest, base, fill, v))
6225 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_int64, 32)
6226 ostreambuf_iterator_char* __thiscall num_put_char_do_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6227         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6228 {
6229     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6230     char fmt[7]; /* strlen("%+#lld")+1 */
6231
6232     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6233
6234     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6235             sprintf(tmp, num_put_char__Ifmt(this, fmt, "lld", base->fmtfl), v));
6236 }
6237
6238 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_J@Z */
6239 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_J@Z */
6240 DEFINE_THISCALL_WRAPPER(num_put_char_put_int64, 32)
6241 ostreambuf_iterator_char* __thiscall num_put_char_put_int64(const num_put *this, ostreambuf_iterator_char *ret,
6242         ostreambuf_iterator_char dest, ios_base *base, char fill, __int64 v)
6243 {
6244     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6245     return call_num_put_char_do_put_int64(this, ret, dest, base, fill, v);
6246 }
6247
6248 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_K@Z */
6249 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_K@Z */
6250 #define call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_char*, \
6251         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, unsigned __int64), \
6252         (this, ret, dest, base, fill, v))
6253 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_uint64, 32)
6254 ostreambuf_iterator_char* __thiscall num_put_char_do_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6255         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6256 {
6257     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6258     char fmt[7]; /* strlen("%+#lld")+1 */
6259
6260     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6261
6262     return num_put_char__Iput(this, ret, dest, base, fill, tmp,
6263             sprintf(tmp, num_put_char__Ifmt(this, fmt, "llu", base->fmtfl), v));
6264 }
6265
6266 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_K@Z */
6267 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_K@Z */
6268 DEFINE_THISCALL_WRAPPER(num_put_char_put_uint64, 32)
6269 ostreambuf_iterator_char* __thiscall num_put_char_put_uint64(const num_put *this, ostreambuf_iterator_char *ret,
6270         ostreambuf_iterator_char dest, ios_base *base, char fill, unsigned __int64 v)
6271 {
6272     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
6273     return call_num_put_char_do_put_uint64(this, ret, dest, base, fill, v);
6274 }
6275
6276 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_N@Z */
6277 /* ?do_put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_N@Z */
6278 #define call_num_put_char_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_char*, \
6279         (const num_put*, ostreambuf_iterator_char*, ostreambuf_iterator_char, ios_base*, char, MSVCP_bool), \
6280         (this, ret, dest, base, fill, v))
6281 DEFINE_THISCALL_WRAPPER(num_put_char_do_put_bool, 28)
6282 ostreambuf_iterator_char* __thiscall num_put_char_do_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6283         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6284 {
6285     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6286
6287     if(base->fmtfl & FMTFLAG_boolalpha) {
6288         numpunct_char *numpunct = numpunct_char_use_facet(base->loc);
6289         basic_string_char str;
6290         MSVCP_size_t pad, len;
6291
6292         if(v)
6293             numpunct_char_truename(numpunct, &str);
6294         else
6295             numpunct_char_falsename(numpunct, &str);
6296
6297         len = basic_string_char_length(&str);
6298         pad = (len>base->wide ? 0 : base->wide-len);
6299         base->wide = 0;
6300
6301         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
6302             num_put_char__Rep(this, &dest, dest, fill, pad);
6303             pad = 0;
6304         }
6305         num_put_char__Putc(this, &dest, dest, basic_string_char_c_str(&str), len);
6306         basic_string_char_dtor(&str);
6307         return num_put_char__Rep(this, ret, dest, fill, pad);
6308     }
6309
6310     return num_put_char_put_long(this, ret, dest, base, fill, v);
6311 }
6312
6313 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AAVios_base@2@D_N@Z */
6314 /* ?put@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@AEAVios_base@2@D_N@Z */
6315 DEFINE_THISCALL_WRAPPER(num_put_char_put_bool, 28)
6316 ostreambuf_iterator_char* __thiscall num_put_char_put_bool(const num_put *this, ostreambuf_iterator_char *ret,
6317         ostreambuf_iterator_char dest, ios_base *base, char fill, MSVCP_bool v)
6318 {
6319     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6320     return call_num_put_char_do_put_bool(this, ret, dest, base, fill, v);
6321 }
6322
6323 /* ?id@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */
6324 static locale_id num_put_wchar_id = {0};
6325 /* ?id@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@2V0locale@2@A */
6326 locale_id num_put_short_id = {0};
6327
6328 /* num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@6B@ */
6329 extern const vtable_ptr MSVCP_num_put_wchar_vtable;
6330 /* num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@6B@ */
6331 extern const vtable_ptr MSVCP_num_put_short_vtable;
6332
6333 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IAEXABV_Locinfo@2@@Z */
6334 /* ?_Init@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@IEAAXAEBV_Locinfo@2@@Z */
6335 DEFINE_THISCALL_WRAPPER(num_put_wchar__Init, 8)
6336 void __thiscall num_put_wchar__Init(num_put *this, const _Locinfo *locinfo)
6337 {
6338     TRACE("(%p %p)\n", this, locinfo);
6339     _Locinfo__Getcvt(locinfo, &this->cvt);
6340 }
6341
6342 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6343 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6344 static num_put* num_put_wchar_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6345 {
6346     TRACE("(%p %p %ld)\n", this, locinfo, refs);
6347
6348     locale_facet_ctor_refs(&this->facet, refs);
6349     this->facet.vtable = &MSVCP_num_put_wchar_vtable;
6350
6351     num_put_wchar__Init(this, locinfo);
6352     return this;
6353 }
6354
6355 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@ABV_Locinfo@1@I@Z */
6356 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@AEBV_Locinfo@1@_K@Z */
6357 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_locinfo, 12)
6358 num_put* __thiscall num_put_short_ctor_locinfo(num_put *this, const _Locinfo *locinfo, MSVCP_size_t refs)
6359 {
6360     num_put_wchar_ctor_locinfo(this, locinfo, refs);
6361     this->facet.vtable = &MSVCP_num_put_short_vtable;
6362     return this;
6363 }
6364
6365 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QAE@I@Z */
6366 /* ??0?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEAA@_K@Z */
6367 static num_put* num_put_wchar_ctor_refs(num_put *this, MSVCP_size_t refs)
6368 {
6369     _Locinfo locinfo;
6370
6371     TRACE("(%p %lu)\n", this, refs);
6372
6373     _Locinfo_ctor(&locinfo);
6374     num_put_wchar_ctor_locinfo(this, &locinfo, refs);
6375     _Locinfo_dtor(&locinfo);
6376     return this;
6377 }
6378
6379 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAE@I@Z */
6380 /* ??0?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAA@_K@Z */
6381 DEFINE_THISCALL_WRAPPER(num_put_short_ctor_refs, 8)
6382 num_put* __thiscall num_put_short_ctor_refs(num_put *this, MSVCP_size_t refs)
6383 {
6384     num_put_wchar_ctor_refs(this, refs);
6385     this->facet.vtable = &MSVCP_num_put_short_vtable;
6386     return this;
6387 }
6388
6389 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QAEXXZ */
6390 /* ??_F?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEAAXXZ */
6391 DEFINE_THISCALL_WRAPPER(num_put_short_ctor, 4)
6392 num_put* __thiscall num_put_short_ctor(num_put *this)
6393 {
6394     return num_put_short_ctor_refs(this, 0);
6395 }
6396
6397 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MAE@XZ */
6398 /* ??1?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEAA@XZ */
6399 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MAE@XZ */
6400 /* ??1?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEAA@XZ */
6401 static void num_put_wchar_dtor(num_put *this)
6402 {
6403     TRACE("(%p)\n", this);
6404     locale_facet_dtor(&this->facet);
6405 }
6406
6407 DEFINE_THISCALL_WRAPPER(num_put_wchar_vector_dtor, 8)
6408 num_put* __thiscall num_put_wchar_vector_dtor(num_put *this, unsigned int flags)
6409 {
6410     TRACE("(%p %x)\n", this, flags);
6411     if(flags & 2) {
6412         /* we have an array, with the number of elements stored before the first object */
6413         INT_PTR i, *ptr = (INT_PTR *)this-1;
6414
6415         for(i=*ptr-1; i>=0; i--)
6416             num_put_wchar_dtor(this+i);
6417         MSVCRT_operator_delete(ptr);
6418     } else {
6419         num_put_wchar_dtor(this);
6420         if(flags & 1)
6421             MSVCRT_operator_delete(this);
6422     }
6423
6424     return this;
6425 }
6426
6427 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
6428 /* ?_Getcat@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
6429 static MSVCP_size_t num_put_wchar__Getcat(const locale_facet **facet, const locale *loc)
6430 {
6431     TRACE("(%p %p)\n", facet, loc);
6432
6433     if(facet && !*facet) {
6434         _Locinfo locinfo;
6435
6436         *facet = MSVCRT_operator_new(sizeof(num_put));
6437         if(!*facet) {
6438             ERR("Out of memory\n");
6439             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6440             return 0;
6441         }
6442
6443         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
6444         num_put_wchar_ctor_locinfo((num_put*)*facet, &locinfo, 0);
6445         _Locinfo_dtor(&locinfo);
6446     }
6447
6448     return LC_NUMERIC;
6449 }
6450
6451 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */
6452 /* ?_Getcat@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */
6453 static MSVCP_size_t num_put_short__Getcat(const locale_facet **facet, const locale *loc)
6454 {
6455     TRACE("(%p %p)\n", facet, loc);
6456
6457     if(facet && !*facet) {
6458         _Locinfo locinfo;
6459
6460         *facet = MSVCRT_operator_new(sizeof(num_put));
6461         if(!*facet) {
6462             ERR("Out of memory\n");
6463             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6464             return 0;
6465         }
6466
6467         _Locinfo_ctor_cstr(&locinfo, basic_string_char_c_str(&loc->ptr->name));
6468         num_put_short_ctor_locinfo((num_put*)*facet, &locinfo, 0);
6469         _Locinfo_dtor(&locinfo);
6470     }
6471
6472     return LC_NUMERIC;
6473 }
6474
6475 static num_put* num_put_wchar_use_facet(const locale *loc)
6476 {
6477     static num_put *obj = NULL;
6478
6479     _Lockit lock;
6480     const locale_facet *fac;
6481
6482     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
6483     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_wchar_id));
6484     if(fac) {
6485         _Lockit_dtor(&lock);
6486         return (num_put*)fac;
6487     }
6488
6489     if(obj) {
6490         _Lockit_dtor(&lock);
6491         return obj;
6492     }
6493
6494     num_put_wchar__Getcat(&fac, loc);
6495     obj = (num_put*)fac;
6496     locale_facet__Incref(&obj->facet);
6497     locale_facet_register(&obj->facet);
6498     _Lockit_dtor(&lock);
6499
6500     return obj;
6501 }
6502
6503 num_put* num_put_short_use_facet(const locale *loc)
6504 {
6505     static num_put *obj = NULL;
6506
6507     _Lockit lock;
6508     const locale_facet *fac;
6509
6510     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
6511     fac = locale__Getfacet(loc, locale_id_operator_size_t(&num_put_short_id));
6512     if(fac) {
6513         _Lockit_dtor(&lock);
6514         return (num_put*)fac;
6515     }
6516
6517     if(obj) {
6518         _Lockit_dtor(&lock);
6519         return obj;
6520     }
6521
6522     num_put_short__Getcat(&fac, loc);
6523     obj = (num_put*)fac;
6524     locale_facet__Incref(&obj->facet);
6525     locale_facet_register(&obj->facet);
6526     _Lockit_dtor(&lock);
6527
6528     return obj;
6529 }
6530
6531 /* ?_Put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PB_WI@Z */
6532 /* ?_Put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PEB_W_K@Z */
6533 /* ?_Put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PBGI@Z */
6534 /* ?_Put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PEBG_K@Z */
6535 static ostreambuf_iterator_wchar* num_put_wchar__Put(const num_put *this, ostreambuf_iterator_wchar *ret,
6536         ostreambuf_iterator_wchar dest, const wchar_t *ptr, MSVCP_size_t count)
6537 {
6538     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_wn(ptr, count), count);
6539
6540     for(; count>0; count--)
6541         ostreambuf_iterator_wchar_put(&dest, *ptr++);
6542
6543     *ret = dest;
6544     return ret;
6545 }
6546
6547 /* ?_Putc@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PBDI@Z */
6548 /* ?_Putc@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@PEBD_K@Z */
6549 /* ?_Putc@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PBDI@Z */
6550 /* ?_Putc@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@PEBD_K@Z */
6551 static ostreambuf_iterator_wchar* num_put_wchar__Putc(const num_put *this, ostreambuf_iterator_wchar *ret,
6552         ostreambuf_iterator_wchar dest, const char *ptr, MSVCP_size_t count)
6553 {
6554     int state = 0;
6555     wchar_t ch;
6556
6557     TRACE("(%p %p %s %ld)\n", this, ret, debugstr_an(ptr, count), count);
6558
6559     for(; count>0; count--) {
6560         if(_Mbrtowc(&ch, ptr++, 1, &state, &this->cvt) == 1)
6561             ostreambuf_iterator_wchar_put(&dest, ch);
6562     }
6563
6564     *ret = dest;
6565     return ret;
6566 }
6567
6568 /* ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_WI@Z */
6569 /* ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_W_K@Z */
6570 /* ?_Rep@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@GI@Z */
6571 /* ?_Rep@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@G_K@Z */
6572 static ostreambuf_iterator_wchar* num_put_wchar__Rep(const num_put *this, ostreambuf_iterator_wchar *ret,
6573         ostreambuf_iterator_wchar dest, wchar_t c, MSVCP_size_t count)
6574 {
6575     TRACE("(%p %p %d %ld)\n", this, ret, c, count);
6576
6577     for(; count>0; count--)
6578         ostreambuf_iterator_wchar_put(&dest, c);
6579
6580     *ret = dest;
6581     return ret;
6582 }
6583
6584 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADDH@Z */
6585 /* ?_Ffmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADDH@Z */
6586 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADDH@Z */
6587 /* ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADDH@Z */
6588 static char* num_put_wchar__Ffmt(const num_put *this, char *fmt, char spec, int fmtfl)
6589 {
6590     int type = fmtfl & FMTFLAG_floatfield;
6591     char *p = fmt;
6592
6593     TRACE("(%p %p %d %d)\n", this, fmt, spec, fmtfl);
6594
6595     *p++ = '%';
6596     if(fmtfl & FMTFLAG_showpos)
6597         *p++ = '+';
6598     if(fmtfl & FMTFLAG_showbase)
6599         *p++ = '#';
6600     *p++ = '.';
6601     *p++ = '*';
6602     if(spec)
6603         *p++ = spec;
6604
6605     if(type == FMTFLAG_fixed)
6606         *p++ = 'f';
6607     else if(type == FMTFLAG_scientific)
6608         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'E' : 'e';
6609     else if(type == (FMTFLAG_fixed|FMTFLAG_scientific))
6610         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'A' : 'a';
6611     else
6612         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'G' : 'g';
6613
6614     *p++ = '\0';
6615     return fmt;
6616 }
6617
6618 /* TODO: This function should be removed when num_put_wchar__Fput is implemented */
6619 static ostreambuf_iterator_wchar* num_put__fput(const num_put *this, ostreambuf_iterator_wchar *ret,
6620         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
6621         MSVCP_size_t count, numpunct_wchar *numpunct)
6622 {
6623     basic_string_char grouping_bstr;
6624     const char *grouping;
6625     char *p, dec_point = *localeconv()->decimal_point;
6626     wchar_t sep;
6627     int cur_group = 0, group_size = 0;
6628     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6629     MSVCP_size_t i, pad;
6630
6631     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6632
6633     for(p=buf; p<buf+count; p++) {
6634         if(*p == dec_point)
6635             break;
6636     }
6637     p--;
6638
6639     /* Add separators to number */
6640     numpunct_wchar_grouping(numpunct, &grouping_bstr);
6641     grouping = basic_string_char_c_str(&grouping_bstr);
6642     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
6643
6644     for(; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6645         group_size++;
6646         if(group_size == grouping[cur_group]) {
6647             group_size = 0;
6648             if(grouping[cur_group+1])
6649                 cur_group++;
6650
6651             memmove(p+1, p, buf+count-p);
6652             *p = '\0'; /* mark thousands separator positions */
6653             count++;
6654         }
6655     }
6656     basic_string_char_dtor(&grouping_bstr);
6657
6658     /* Display number with padding */
6659     if(count >= base->wide)
6660         pad = 0;
6661     else
6662         pad = base->wide-count;
6663     base->wide = 0;
6664
6665     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6666         num_put_wchar__Putc(this, &dest, dest, buf, 1);
6667         buf++;
6668     }
6669     if(adjustfield != FMTFLAG_left) {
6670         num_put_wchar__Rep(this, ret, dest, fill, pad);
6671         pad = 0;
6672     }
6673
6674     for(i=0; i<count; i++) {
6675         if(buf[i] == dec_point)
6676             num_put_wchar__Rep(this, &dest, dest, numpunct_wchar_decimal_point(numpunct), 1);
6677         else if(!buf[i])
6678             num_put_wchar__Rep(this, &dest, dest, sep, 1);
6679         else
6680             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
6681     }
6682
6683     return num_put_wchar__Rep(this, ret, dest, fill, pad);
6684 }
6685
6686 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAPADPADPBDH@Z */
6687 /* ?_Ifmt@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
6688 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADPBDH@Z */
6689 /* ?_Ifmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAPEADPEADPEBDH@Z */
6690 static char* num_put_wchar__Ifmt(const num_put *this, char *fmt, const char *spec, int fmtfl)
6691 {
6692     int base = fmtfl & FMTFLAG_basefield;
6693     char *p = fmt;
6694
6695     TRACE("(%p %p %p %d)\n", this, fmt, spec, fmtfl);
6696
6697     *p++ = '%';
6698     if(fmtfl & FMTFLAG_showpos)
6699         *p++ = '+';
6700     if(fmtfl & FMTFLAG_showbase)
6701         *p++ = '#';
6702
6703     *p++ = *spec++;
6704     if(*spec == 'l')
6705         *p++ = *spec++;
6706
6707     if(base == FMTFLAG_oct)
6708         *p++ = 'o';
6709     else if(base == FMTFLAG_hex)
6710         *p++ = (fmtfl & FMTFLAG_uppercase) ? 'X' : 'x';
6711     else
6712         *p++ = *spec;
6713
6714     *p++ = '\0';
6715     return fmt;
6716 }
6717
6718 static ostreambuf_iterator_wchar* num_put__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
6719         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf,
6720         MSVCP_size_t count, numpunct_wchar *numpunct)
6721 {
6722     basic_string_char grouping_bstr;
6723     const char *grouping;
6724     char *p;
6725     wchar_t sep;
6726     int cur_group = 0, group_size = 0;
6727     int adjustfield = base->fmtfl & FMTFLAG_adjustfield;
6728     MSVCP_size_t i, pad;
6729
6730     TRACE("(%p %p %p %d %s %ld)\n", this, ret, base, fill, buf, count);
6731
6732     /* Add separators to number */
6733     numpunct_wchar_grouping(numpunct, &grouping_bstr);
6734     grouping = basic_string_char_c_str(&grouping_bstr);
6735     sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
6736
6737     for(p=buf+count-1; p>buf && sep && grouping[cur_group]!=CHAR_MAX; p--) {
6738         group_size++;
6739         if(group_size == grouping[cur_group]) {
6740             group_size = 0;
6741             if(grouping[cur_group+1])
6742                 cur_group++;
6743
6744             memmove(p+1, p, buf+count-p);
6745             *p = '\0'; /* mark thousands separator positions */
6746             count++;
6747         }
6748     }
6749     basic_string_char_dtor(&grouping_bstr);
6750
6751     /* Display number with padding */
6752     if(count >= base->wide)
6753         pad = 0;
6754     else
6755         pad = base->wide-count;
6756     base->wide = 0;
6757
6758     if((adjustfield & FMTFLAG_internal) && (buf[0]=='-' || buf[0]=='+')) {
6759         num_put_wchar__Putc(this, &dest, dest, buf, 1);
6760         buf++;
6761     }else if((adjustfield & FMTFLAG_internal) && (buf[1]=='x' || buf[1]=='X')) {
6762         num_put_wchar__Putc(this, &dest, dest, buf, 2);
6763         buf += 2;
6764     }
6765     if(adjustfield != FMTFLAG_left) {
6766         num_put_wchar__Rep(this, ret, dest, fill, pad);
6767         pad = 0;
6768     }
6769
6770     for(i=0; i<count; i++) {
6771         if(!buf[i])
6772             num_put_wchar__Rep(this, &dest, dest, sep, 1);
6773         else
6774             num_put_wchar__Putc(this, &dest, dest, buf+i, 1);
6775     }
6776
6777     return num_put_wchar__Rep(this, ret, dest, fill, pad);
6778 }
6779
6780 /* ?_Iput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPADI@Z */
6781 /* ?_Iput@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEAD_K@Z */
6782 static ostreambuf_iterator_wchar* num_put_wchar__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
6783         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
6784 {
6785     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_wchar_use_facet(base->loc));
6786 }
6787
6788 /* ?_Iput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPADI@Z */
6789 /* ?_Iput@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEAD_K@Z */
6790 static ostreambuf_iterator_wchar* num_put_short__Iput(const num_put *this, ostreambuf_iterator_wchar *ret,
6791         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, char *buf, MSVCP_size_t count)
6792 {
6793     return num_put__Iput(this, ret, dest, base, fill, buf, count, numpunct_short_use_facet(base->loc));
6794 }
6795
6796 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WJ@Z */
6797 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WJ@Z */
6798 #define call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 28, ostreambuf_iterator_wchar*, \
6799         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, LONG), \
6800         (this, ret, dest, base, fill, v))
6801 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_long, 28)
6802 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
6803         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
6804 {
6805     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6806     char fmt[7]; /* strlen("%+#lld")+1 */
6807
6808     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6809
6810     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
6811             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
6812 }
6813
6814 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GJ@Z */
6815 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GJ@Z */
6816 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_long, 28)
6817 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
6818         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
6819 {
6820     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6821     char fmt[7]; /* strlen("%+#lld")+1 */
6822
6823     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6824
6825     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
6826             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "ld", base->fmtfl), v));
6827 }
6828
6829 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WJ@Z */
6830 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WJ@Z */
6831 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GJ@Z */
6832 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GJ@Z */
6833 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_long, 28)
6834 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_long(const num_put *this, ostreambuf_iterator_wchar *ret,
6835         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, LONG v)
6836 {
6837     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6838     return call_num_put_wchar_do_put_long(this, ret, dest, base, fill, v);
6839 }
6840
6841 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WK@Z */
6842 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WK@Z */
6843 #define call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 24, ostreambuf_iterator_wchar*, \
6844         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, ULONG), \
6845         (this, ret, dest, base, fill, v))
6846 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ulong, 28)
6847 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
6848         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
6849 {
6850     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6851     char fmt[7]; /* strlen("%+#lld")+1 */
6852
6853     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6854
6855     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
6856             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
6857 }
6858
6859 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GK@Z */
6860 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GK@Z */
6861 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ulong, 28)
6862 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
6863         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
6864 {
6865     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
6866     char fmt[7]; /* strlen("%+#lld")+1 */
6867
6868     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6869
6870     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
6871             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lu", base->fmtfl), v));
6872 }
6873
6874 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WK@Z */
6875 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WK@Z */
6876 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GK@Z */
6877 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GK@Z */
6878 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ulong, 28)
6879 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ulong(const num_put *this, ostreambuf_iterator_wchar *ret,
6880         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, ULONG v)
6881 {
6882     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
6883     return call_num_put_wchar_do_put_ulong(this, ret, dest, base, fill, v);
6884 }
6885
6886 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WN@Z */
6887 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WN@Z */
6888 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WO@Z */
6889 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WO@Z */
6890 #define call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 12, ostreambuf_iterator_wchar*, \
6891         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
6892         (this, ret, dest, base, fill, v))
6893 #define call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 8, ostreambuf_iterator_wchar*, \
6894         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, double), \
6895         (this, ret, dest, base, fill, v))
6896 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_double, 32)
6897 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
6898         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
6899 {
6900     char *tmp;
6901     char fmt[8]; /* strlen("%+#.*lg")+1 */
6902     int size;
6903
6904     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6905
6906     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
6907     size = _scprintf(fmt, base->prec, v);
6908
6909     /* TODO: don't use dynamic allocation */
6910     tmp = MSVCRT_operator_new(size*2);
6911     if(!tmp) {
6912         ERR("Out of memory\n");
6913         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6914     }
6915     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, base->prec, v),
6916             numpunct_wchar_use_facet(base->loc));
6917     MSVCRT_operator_delete(tmp);
6918     return ret;
6919 }
6920
6921 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GN@Z */
6922 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GN@Z */
6923 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GO@Z */
6924 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GO@Z */
6925 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_double, 32)
6926 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
6927         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
6928 {
6929     char *tmp;
6930     char fmt[8]; /* strlen("%+#.*lg")+1 */
6931     int size;
6932     streamsize prec;
6933
6934     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6935
6936     num_put_wchar__Ffmt(this, fmt, '\0', base->fmtfl);
6937     prec = get_precision(base);
6938     size = _scprintf(fmt, prec, v);
6939
6940     /* TODO: don't use dynamic allocation */
6941     tmp = MSVCRT_operator_new(size*2);
6942     if(!tmp) {
6943         ERR("Out of memory\n");
6944         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
6945     }
6946     num_put__fput(this, ret, dest, base, fill, tmp, sprintf(tmp, fmt, prec, v),
6947             numpunct_short_use_facet(base->loc));
6948     MSVCRT_operator_delete(tmp);
6949     return ret;
6950 }
6951
6952 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WN@Z */
6953 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WN@Z */
6954 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GN@Z */
6955 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GN@Z */
6956 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_double, 32)
6957 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_double(const num_put *this, ostreambuf_iterator_wchar *ret,
6958         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
6959 {
6960     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6961     return call_num_put_wchar_do_put_double(this, ret, dest, base, fill, v);
6962 }
6963
6964 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WO@Z */
6965 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WO@Z */
6966 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GO@Z */
6967 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GO@Z */
6968 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ldouble, 32)
6969 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ldouble(const num_put *this, ostreambuf_iterator_wchar *ret,
6970         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, double v)
6971 {
6972     TRACE("(%p %p %p %d %lf)\n", this, ret, base, fill, v);
6973     return call_num_put_wchar_do_put_ldouble(this, ret, dest, base, fill, v);
6974 }
6975
6976 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPBX@Z */
6977 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEBX@Z */
6978 #define call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 4, ostreambuf_iterator_wchar*, \
6979         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, const void*), \
6980         (this, ret, dest, base, fill, v))
6981 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_ptr, 28)
6982 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
6983         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
6984 {
6985     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
6986
6987     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
6988
6989     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
6990 }
6991
6992 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPBX@Z */
6993 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEBX@Z */
6994 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_ptr, 28)
6995 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
6996         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
6997 {
6998     char tmp[17]; /* 8(16^8==2^64)*2(separators beetwen every digit) + 1 */
6999
7000     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7001
7002     return num_put_short__Iput(this, ret, dest, base, fill, tmp, sprintf(tmp, "%p", v));
7003 }
7004
7005 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_WPBX@Z */
7006 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_WPEBX@Z */
7007 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@GPBX@Z */
7008 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@GPEBX@Z */
7009 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_ptr, 28)
7010 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_ptr(const num_put *this, ostreambuf_iterator_wchar *ret,
7011         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, const void *v)
7012 {
7013     TRACE("(%p %p %p %d %p)\n", this, ret, base, fill, v);
7014     return call_num_put_wchar_do_put_ptr(this, ret, dest, base, fill, v);
7015 }
7016
7017 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_J@Z */
7018 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_J@Z */
7019 #define call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 20, ostreambuf_iterator_wchar*, \
7020         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, __int64), \
7021         (this, ret, dest, base, fill, v))
7022 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_int64, 32)
7023 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7024         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7025 {
7026     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7027     char fmt[7]; /* strlen("%+#lld")+1 */
7028
7029     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7030
7031     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7032             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7033 }
7034
7035 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_J@Z */
7036 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_J@Z */
7037 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_int64, 32)
7038 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7039         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7040 {
7041     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7042     char fmt[7]; /* strlen("%+#lld")+1 */
7043
7044     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7045
7046     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7047             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "lld", base->fmtfl), v));
7048 }
7049
7050 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_J@Z */
7051 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_J@Z */
7052 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_J@Z */
7053 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_J@Z */
7054 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_int64, 32)
7055 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_int64(const num_put *this, ostreambuf_iterator_wchar *ret,
7056         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, __int64 v)
7057 {
7058     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7059     return call_num_put_wchar_do_put_int64(this, ret, dest, base, fill, v);
7060 }
7061
7062 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_K@Z */
7063 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_K@Z */
7064 #define call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 16, ostreambuf_iterator_wchar*, \
7065         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, unsigned __int64), \
7066         (this, ret, dest, base, fill, v))
7067 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_uint64, 32)
7068 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7069         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7070 {
7071     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7072     char fmt[7]; /* strlen("%+#lld")+1 */
7073
7074     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7075
7076     return num_put_wchar__Iput(this, ret, dest, base, fill, tmp,
7077             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7078 }
7079
7080 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_K@Z */
7081 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_K@Z */
7082 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_uint64, 32)
7083 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7084         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7085 {
7086     char tmp[48]; /* 22(8^22>2^64)*2(separators beetwen every digit) + 3(strlen("+0x"))+1 */
7087     char fmt[7]; /* strlen("%+#lld")+1 */
7088
7089     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7090
7091     return num_put_short__Iput(this, ret, dest, base, fill, tmp,
7092             sprintf(tmp, num_put_wchar__Ifmt(this, fmt, "llu", base->fmtfl), v));
7093 }
7094
7095 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_K@Z */
7096 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_K@Z */
7097 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_K@Z */
7098 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_K@Z */
7099 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_uint64, 32)
7100 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_uint64(const num_put *this, ostreambuf_iterator_wchar *ret,
7101         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, unsigned __int64 v)
7102 {
7103     TRACE("(%p %p %p %d)\n", this, ret, base, fill);
7104     return call_num_put_wchar_do_put_uint64(this, ret, dest, base, fill, v);
7105 }
7106
7107 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_N@Z */
7108 /* ?do_put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_N@Z */
7109 #define call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v) CALL_VTBL_FUNC(this, 32, ostreambuf_iterator_wchar*, \
7110         (const num_put*, ostreambuf_iterator_wchar*, ostreambuf_iterator_wchar, ios_base*, wchar_t, MSVCP_bool), \
7111         (this, ret, dest, base, fill, v))
7112 DEFINE_THISCALL_WRAPPER(num_put_wchar_do_put_bool, 28)
7113 ostreambuf_iterator_wchar* __thiscall num_put_wchar_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7114         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7115 {
7116     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7117
7118     if(base->fmtfl & FMTFLAG_boolalpha) {
7119         numpunct_wchar *numpunct = numpunct_wchar_use_facet(base->loc);
7120         basic_string_wchar str;
7121         MSVCP_size_t pad, len;
7122
7123         if(v)
7124             numpunct_wchar_truename(numpunct, &str);
7125         else
7126             numpunct_wchar_falsename(numpunct, &str);
7127
7128         len = basic_string_wchar_length(&str);
7129         pad = (len>base->wide ? 0 : base->wide-len);
7130         base->wide = 0;
7131
7132         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7133             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7134             pad = 0;
7135         }
7136         num_put_wchar__Put(this, &dest, dest, basic_string_wchar_c_str(&str), len);
7137         basic_string_wchar_dtor(&str);
7138         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7139     }
7140
7141     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7142 }
7143
7144 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_N@Z */
7145 /* ?do_put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@MEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_N@Z */
7146 DEFINE_THISCALL_WRAPPER(num_put_short_do_put_bool, 28)
7147 ostreambuf_iterator_wchar* __thiscall num_put_short_do_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7148         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7149 {
7150     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7151
7152     if(base->fmtfl & FMTFLAG_boolalpha) {
7153         numpunct_wchar *numpunct = numpunct_short_use_facet(base->loc);
7154         basic_string_wchar str;
7155         MSVCP_size_t pad, len;
7156
7157         if(v)
7158             numpunct_wchar_truename(numpunct, &str);
7159         else
7160             numpunct_wchar_falsename(numpunct, &str);
7161
7162         len = basic_string_wchar_length(&str);
7163         pad = (len>base->wide ? 0 : base->wide-len);
7164         base->wide = 0;
7165
7166         if((base->fmtfl & FMTFLAG_adjustfield) != FMTFLAG_left) {
7167             num_put_wchar__Rep(this, &dest, dest, fill, pad);
7168             pad = 0;
7169         }
7170         num_put_wchar__Put(this, &dest, dest, basic_string_wchar_c_str(&str), len);
7171         basic_string_wchar_dtor(&str);
7172         return num_put_wchar__Rep(this, ret, dest, fill, pad);
7173     }
7174
7175     return num_put_wchar_put_long(this, ret, dest, base, fill, v);
7176 }
7177
7178 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AAVios_base@2@_W_N@Z */
7179 /* ?put@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@AEAVios_base@2@_W_N@Z */
7180 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QBE?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AAVios_base@2@G_N@Z */
7181 /* ?put@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@QEBA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@AEAVios_base@2@G_N@Z */
7182 DEFINE_THISCALL_WRAPPER(num_put_wchar_put_bool, 28)
7183 ostreambuf_iterator_wchar* __thiscall num_put_wchar_put_bool(const num_put *this, ostreambuf_iterator_wchar *ret,
7184         ostreambuf_iterator_wchar dest, ios_base *base, wchar_t fill, MSVCP_bool v)
7185 {
7186     TRACE("(%p %p %p %d %d)\n", this, ret, base, fill, v);
7187     return call_num_put_wchar_do_put_bool(this, ret, dest, base, fill, v);
7188 }
7189
7190 /* ??0_Locimp@locale@std@@AAE@_N@Z */
7191 /* ??0_Locimp@locale@std@@AEAA@_N@Z */
7192 static locale__Locimp* locale__Locimp_ctor_transparent(locale__Locimp *this, MSVCP_bool transparent)
7193 {
7194     TRACE("(%p %d)\n", this, transparent);
7195
7196     memset(this, 0, sizeof(locale__Locimp));
7197     locale_facet_ctor_refs(&this->facet, 1);
7198     this->transparent = transparent;
7199     basic_string_char_ctor_cstr(&this->name, "*");
7200     return this;
7201 }
7202
7203 /* ??_F_Locimp@locale@std@@QAEXXZ */
7204 /* ??_F_Locimp@locale@std@@QEAAXXZ */
7205 static locale__Locimp* locale__Locimp_ctor(locale__Locimp *this)
7206 {
7207     return locale__Locimp_ctor_transparent(this, FALSE);
7208 }
7209
7210 /* ??0_Locimp@locale@std@@AAE@ABV012@@Z */
7211 /* ??0_Locimp@locale@std@@AEAA@AEBV012@@Z */
7212 static locale__Locimp* locale__Locimp_copy_ctor(locale__Locimp *this, const locale__Locimp *copy)
7213 {
7214     _Lockit lock;
7215     MSVCP_size_t i;
7216
7217     TRACE("(%p %p)\n", this, copy);
7218
7219     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7220     memcpy(this, copy, sizeof(locale__Locimp));
7221     locale_facet_ctor_refs(&this->facet, 1);
7222     if(copy->facetvec) {
7223         this->facetvec = MSVCRT_operator_new(copy->facet_cnt*sizeof(locale_facet*));
7224         if(!this->facetvec) {
7225             _Lockit_dtor(&lock);
7226             ERR("Out of memory\n");
7227             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7228             return NULL;
7229         }
7230         for(i=0; i<this->facet_cnt; i++)
7231         {
7232             this->facetvec[i] = copy->facetvec[i];
7233             if(this->facetvec[i])
7234                 locale_facet__Incref(this->facetvec[i]);
7235         }
7236     }
7237     basic_string_char_copy_ctor(&this->name, &copy->name);
7238     _Lockit_dtor(&lock);
7239     return this;
7240 }
7241
7242 /* ??1_Locimp@locale@std@@MAE@XZ */
7243 /* ??1_Locimp@locale@std@@MEAA@XZ */
7244 static void locale__Locimp_dtor(locale__Locimp *this)
7245 {
7246     MSVCP_size_t i;
7247
7248     TRACE("(%p)\n", this);
7249
7250     locale_facet_dtor(&this->facet);
7251     for(i=0; i<this->facet_cnt; i++)
7252         if(this->facetvec[i] && locale_facet__Decref(this->facetvec[i]))
7253             call_locale_facet_vector_dtor(this->facetvec[i], 1);
7254
7255     MSVCRT_operator_delete(this->facetvec);
7256     basic_string_char_dtor(&this->name);
7257 }
7258
7259 DEFINE_THISCALL_WRAPPER(locale__Locimp_vector_dtor, 8)
7260 locale__Locimp* __thiscall locale__Locimp_vector_dtor(locale__Locimp *this, unsigned int flags)
7261 {
7262     TRACE("(%p %x)\n", this, flags);
7263     if(flags & 2) {
7264         /* we have an array, with the number of elements stored before the first object */
7265         INT_PTR i, *ptr = (INT_PTR *)this-1;
7266
7267         for(i=*ptr-1; i>=0; i--)
7268             locale__Locimp_dtor(this+i);
7269         MSVCRT_operator_delete(ptr);
7270     } else {
7271         locale__Locimp_dtor(this);
7272         if(flags & 1)
7273             MSVCRT_operator_delete(this);
7274     }
7275
7276     return this;
7277 }
7278
7279 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z */
7280 /* ?_Locimp_Addfac@_Locimp@locale@std@@CAXPEAV123@PEAVfacet@23@_K@Z */
7281 static void locale__Locimp__Locimp_Addfac(locale__Locimp *locimp, locale_facet *facet, MSVCP_size_t id)
7282 {
7283     _Lockit lock;
7284
7285     TRACE("(%p %p %lu)\n", locimp, facet, id);
7286
7287     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7288     if(id >= locimp->facet_cnt) {
7289         MSVCP_size_t new_size = id+1;
7290         locale_facet **new_facetvec;
7291
7292         if(new_size < locale_id__Id_cnt+1)
7293             new_size = locale_id__Id_cnt+1;
7294
7295         new_facetvec = MSVCRT_operator_new(sizeof(locale_facet*)*new_size);
7296         if(!new_facetvec) {
7297             _Lockit_dtor(&lock);
7298             ERR("Out of memory\n");
7299             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7300             return;
7301         }
7302
7303         memset(new_facetvec, 0, sizeof(locale_facet*)*new_size);
7304         memcpy(new_facetvec, locimp->facetvec, sizeof(locale_facet*)*locimp->facet_cnt);
7305         MSVCRT_operator_delete(locimp->facetvec);
7306         locimp->facetvec = new_facetvec;
7307         locimp->facet_cnt = new_size;
7308     }
7309
7310     if(locimp->facetvec[id] && locale_facet__Decref(locimp->facetvec[id]))
7311         call_locale_facet_vector_dtor(locimp->facetvec[id], 1);
7312
7313     locimp->facetvec[id] = facet;
7314     if(facet)
7315         locale_facet__Incref(facet);
7316     _Lockit_dtor(&lock);
7317 }
7318
7319 /* ?_Addfac@_Locimp@locale@std@@AAEXPAVfacet@23@I@Z */
7320 /* ?_Addfac@_Locimp@locale@std@@AEAAXPEAVfacet@23@_K@Z */
7321 static void locale__Locimp__Addfac(locale__Locimp *this, locale_facet *facet, MSVCP_size_t id)
7322 {
7323     locale__Locimp__Locimp_Addfac(this, facet, id);
7324 }
7325
7326 /* ?_Makeushloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
7327 /* ?_Makeushloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7328 /* List of missing facets:
7329  * num_put, collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
7330  */
7331 static void locale__Locimp__Makeushloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7332 {
7333     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
7334
7335     if(cat & (1<<(ctype_short__Getcat(NULL, NULL)-1))) {
7336         ctype_wchar *ctype;
7337
7338         if(loc) {
7339             ctype = ctype_short_use_facet(loc);
7340         }else {
7341             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
7342             if(!ctype) {
7343                 ERR("Out of memory\n");
7344                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7345             }
7346             ctype_short_ctor_locinfo(ctype, locinfo, 0);
7347         }
7348         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_short_id));
7349     }
7350
7351     if(cat & (1<<(num_get_short__Getcat(NULL, NULL)-1))) {
7352         num_get *numget;
7353
7354         if(loc) {
7355             numget = num_get_short_use_facet(loc);
7356         }else {
7357             numget = MSVCRT_operator_new(sizeof(num_get));
7358             if(!numget) {
7359                 ERR("Out of memory\n");
7360                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7361             }
7362             num_get_short_ctor_locinfo(numget, locinfo, 0);
7363         }
7364         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_short_id));
7365     }
7366
7367     if(cat & (1<<(num_put_short__Getcat(NULL, NULL)-1))) {
7368         num_put *numput;
7369
7370         if(loc) {
7371             numput = num_put_short_use_facet(loc);
7372         }else {
7373             numput = MSVCRT_operator_new(sizeof(num_put));
7374             if(!numput) {
7375                 ERR("Out of memory\n");
7376                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7377             }
7378             num_put_short_ctor_locinfo(numput, locinfo, 0);
7379         }
7380         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_short_id));
7381     }
7382
7383     if(cat & (1<<(numpunct_short__Getcat(NULL, NULL)-1))) {
7384         numpunct_wchar *numpunct;
7385
7386         if(loc) {
7387             numpunct = numpunct_short_use_facet(loc);
7388         }else {
7389             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
7390             if(!numpunct) {
7391                 ERR("Out of memory\n");
7392                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7393             }
7394             numpunct_short_ctor_locinfo(numpunct, locinfo, 0, FALSE);
7395         }
7396         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_short_id));
7397     }
7398
7399     if(cat & (1<<(codecvt_short__Getcat(NULL, NULL)-1))) {
7400         codecvt_wchar *codecvt;
7401
7402         if(loc) {
7403             codecvt = codecvt_short_use_facet(loc);
7404         }else {
7405             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
7406             if(!codecvt) {
7407                 ERR("Out of memory\n");
7408                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7409             }
7410             codecvt_short_ctor_locinfo(codecvt, locinfo, 0);
7411         }
7412         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_short_id));
7413     }
7414 }
7415
7416 /* ?_Makewloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
7417 /* ?_Makewloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7418 /* List of missing facets:
7419  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
7420  */
7421 static void locale__Locimp__Makewloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7422 {
7423     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
7424
7425     if(cat & (1<<(ctype_wchar__Getcat(NULL, NULL)-1))) {
7426         ctype_wchar *ctype;
7427
7428         if(loc) {
7429             ctype = ctype_wchar_use_facet(loc);
7430         }else {
7431             ctype = MSVCRT_operator_new(sizeof(ctype_wchar));
7432             if(!ctype) {
7433                 ERR("Out of memory\n");
7434                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7435             }
7436             ctype_wchar_ctor_locinfo(ctype, locinfo, 0);
7437         }
7438         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_wchar_id));
7439     }
7440
7441     if(cat & (1<<(num_get_wchar__Getcat(NULL, NULL)-1))) {
7442         num_get *numget;
7443
7444         if(loc) {
7445             numget = num_get_wchar_use_facet(loc);
7446         }else {
7447             numget = MSVCRT_operator_new(sizeof(num_get));
7448             if(!numget) {
7449                 ERR("Out of memory\n");
7450                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7451             }
7452             num_get_wchar_ctor_locinfo(numget, locinfo, 0);
7453         }
7454         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_wchar_id));
7455     }
7456
7457     if(cat & (1<<(num_put_wchar__Getcat(NULL, NULL)-1))) {
7458         num_put *numput;
7459
7460         if(loc) {
7461             numput = num_put_wchar_use_facet(loc);
7462         }else {
7463             numput = MSVCRT_operator_new(sizeof(num_put));
7464             if(!numput) {
7465                 ERR("Out of memory\n");
7466                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7467             }
7468             num_put_wchar_ctor_locinfo(numput, locinfo, 0);
7469         }
7470         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_wchar_id));
7471     }
7472
7473     if(cat & (1<<(numpunct_wchar__Getcat(NULL, NULL)-1))) {
7474         numpunct_wchar *numpunct;
7475
7476         if(loc) {
7477             numpunct = numpunct_wchar_use_facet(loc);
7478         }else {
7479             numpunct = MSVCRT_operator_new(sizeof(numpunct_wchar));
7480             if(!numpunct) {
7481                 ERR("Out of memory\n");
7482                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7483             }
7484             numpunct_wchar_ctor_locinfo(numpunct, locinfo, 0, FALSE);
7485         }
7486         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_wchar_id));
7487     }
7488
7489     if(cat & (1<<(codecvt_wchar__Getcat(NULL, NULL)-1))) {
7490         codecvt_wchar *codecvt;
7491
7492         if(loc) {
7493             codecvt = codecvt_wchar_use_facet(loc);
7494         }else {
7495             codecvt = MSVCRT_operator_new(sizeof(codecvt_wchar));
7496             if(!codecvt) {
7497                 ERR("Out of memory\n");
7498                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7499             }
7500             codecvt_wchar_ctor_locinfo(codecvt, locinfo, 0);
7501         }
7502         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_wchar_id));
7503     }
7504 }
7505
7506 /* ?_Makexloc@_Locimp@locale@std@@CAXABV_Locinfo@3@HPAV123@PBV23@@Z */
7507 /* ?_Makexloc@_Locimp@locale@std@@CAXAEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7508 /* List of missing facets:
7509  * collate, messages, money_get, money_put, moneypunct, moneypunct, time_get, time_put
7510  */
7511 static void locale__Locimp__Makexloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7512 {
7513     FIXME("(%p %d %p %p) semi-stub\n", locinfo, cat, locimp, loc);
7514
7515     if(cat & (1<<(ctype_char__Getcat(NULL, NULL)-1))) {
7516         ctype_char *ctype;
7517
7518         if(loc) {
7519             ctype = ctype_char_use_facet(loc);
7520         }else {
7521             ctype = MSVCRT_operator_new(sizeof(ctype_char));
7522             if(!ctype) {
7523                 ERR("Out of memory\n");
7524                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7525             }
7526             ctype_char_ctor_locinfo(ctype, locinfo, 0);
7527         }
7528         locale__Locimp__Addfac(locimp, &ctype->base.facet, locale_id_operator_size_t(&ctype_char_id));
7529     }
7530
7531     if(cat & (1<<(num_get_char__Getcat(NULL, NULL)-1))) {
7532         num_get *numget;
7533
7534         if(loc) {
7535             numget = num_get_char_use_facet(loc);
7536         }else {
7537             numget = MSVCRT_operator_new(sizeof(num_get));
7538             if(!numget) {
7539                 ERR("Out of memory\n");
7540                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7541             }
7542             num_get_char_ctor_locinfo(numget, locinfo, 0);
7543         }
7544         locale__Locimp__Addfac(locimp, &numget->facet, locale_id_operator_size_t(&num_get_char_id));
7545     }
7546
7547     if(cat & (1<<(num_put_char__Getcat(NULL, NULL)-1))) {
7548         num_put *numput;
7549
7550         if(loc) {
7551             numput = num_put_char_use_facet(loc);
7552         }else {
7553             numput = MSVCRT_operator_new(sizeof(num_put));
7554             if(!numput) {
7555                 ERR("Out of memory\n");
7556                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7557             }
7558             num_put_char_ctor_locinfo(numput, locinfo, 0);
7559         }
7560         locale__Locimp__Addfac(locimp, &numput->facet, locale_id_operator_size_t(&num_put_char_id));
7561     }
7562
7563     if(cat & (1<<(numpunct_char__Getcat(NULL, NULL)-1))) {
7564         numpunct_char *numpunct;
7565
7566         if(loc) {
7567             numpunct = numpunct_char_use_facet(loc);
7568         }else {
7569             numpunct = MSVCRT_operator_new(sizeof(numpunct_char));
7570             if(!numpunct) {
7571                 ERR("Out of memory\n");
7572                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7573             }
7574             numpunct_char_ctor_locinfo(numpunct, locinfo, 0, FALSE);
7575         }
7576         locale__Locimp__Addfac(locimp, &numpunct->facet, locale_id_operator_size_t(&numpunct_char_id));
7577     }
7578
7579     if(cat & (1<<(codecvt_char__Getcat(NULL, NULL)-1))) {
7580         codecvt_char *codecvt;
7581
7582         if(loc) {
7583             codecvt = codecvt_char_use_facet(loc);
7584         }else {
7585             codecvt = MSVCRT_operator_new(sizeof(codecvt_char));
7586             if(!codecvt) {
7587                 ERR("Out of memory\n");
7588                 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7589             }
7590             codecvt_char_ctor_locinfo(codecvt, locinfo, 0);
7591         }
7592         locale__Locimp__Addfac(locimp, &codecvt->base.facet, locale_id_operator_size_t(&codecvt_char_id));
7593     }
7594 }
7595
7596 /* ?_Makeloc@_Locimp@locale@std@@CAPAV123@ABV_Locinfo@3@HPAV123@PBV23@@Z */
7597 /* ?_Makeloc@_Locimp@locale@std@@CAPEAV123@AEBV_Locinfo@3@HPEAV123@PEBV23@@Z */
7598 static locale__Locimp* locale__Locimp__Makeloc(const _Locinfo *locinfo, category cat, locale__Locimp *locimp, const locale *loc)
7599 {
7600     TRACE("(%p %d %p %p)\n", locinfo, cat, locimp, loc);
7601
7602     locale__Locimp__Makexloc(locinfo, cat, locimp, loc);
7603     locale__Locimp__Makewloc(locinfo, cat, locimp, loc);
7604     locale__Locimp__Makeushloc(locinfo, cat, locimp, loc);
7605
7606     locimp->catmask |= cat;
7607     basic_string_char_copy_ctor(&locimp->name, &locinfo->newlocname);
7608     return locimp;
7609 }
7610
7611 /* ??_7_Locimp@locale@std@@6B@ */
7612 const vtable_ptr MSVCP_locale__Locimp_vtable[] = {
7613     (vtable_ptr)THISCALL_NAME(locale__Locimp_vector_dtor)
7614 };
7615
7616 /* ??0locale@std@@AAE@PAV_Locimp@01@@Z */
7617 /* ??0locale@std@@AEAA@PEAV_Locimp@01@@Z */
7618 DEFINE_THISCALL_WRAPPER(locale_ctor_locimp, 8)
7619 locale* __thiscall locale_ctor_locimp(locale *this, locale__Locimp *locimp)
7620 {
7621     TRACE("(%p %p)\n", this, locimp);
7622     /* Don't change locimp reference counter */
7623     this->ptr = locimp;
7624     return this;
7625 }
7626
7627 /* ?_Init@locale@std@@CAPAV_Locimp@12@XZ */
7628 /* ?_Init@locale@std@@CAPEAV_Locimp@12@XZ */
7629 locale__Locimp* __cdecl locale__Init(void)
7630 {
7631     _Lockit lock;
7632
7633     TRACE("\n");
7634
7635     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7636     if(global_locale) {
7637         _Lockit_dtor(&lock);
7638         return global_locale;
7639     }
7640
7641     global_locale = MSVCRT_operator_new(sizeof(locale__Locimp));
7642     if(!global_locale) {
7643         _Lockit_dtor(&lock);
7644         ERR("Out of memory\n");
7645         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7646         return NULL;
7647     }
7648
7649     locale__Locimp_ctor(global_locale);
7650     global_locale->catmask = (1<<(LC_MAX+1))-1;
7651     basic_string_char_dtor(&global_locale->name);
7652     basic_string_char_ctor_cstr(&global_locale->name, "C");
7653
7654     locale__Locimp__Clocptr = global_locale;
7655     global_locale->facet.refs++;
7656     locale_ctor_locimp(&classic_locale, locale__Locimp__Clocptr);
7657     _Lockit_dtor(&lock);
7658
7659     return global_locale;
7660 }
7661
7662 /* ??0locale@std@@QAE@ABV01@0H@Z */
7663 /* ??0locale@std@@QEAA@AEBV01@0H@Z */
7664 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_locale, 16)
7665 locale* __thiscall locale_ctor_locale_locale(locale *this, const locale *loc, const locale *other, category cat)
7666 {
7667     _Locinfo locinfo;
7668
7669     TRACE("(%p %p %p %d)\n", this, loc, other, cat);
7670
7671     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
7672     if(!this->ptr) {
7673         ERR("Out of memory\n");
7674         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7675     }
7676     locale__Locimp_copy_ctor(this->ptr, loc->ptr);
7677
7678     _Locinfo_ctor_cat_cstr(&locinfo, loc->ptr->catmask, basic_string_char_c_str(&loc->ptr->name));
7679     _Locinfo__Addcats(&locinfo, cat & other->ptr->catmask, basic_string_char_c_str(&other->ptr->name));
7680     locale__Locimp__Makeloc(&locinfo, cat, this->ptr, other);
7681     _Locinfo_dtor(&locinfo);
7682
7683     return this;
7684 }
7685
7686 /* ??0locale@std@@QAE@ABV01@@Z */
7687 /* ??0locale@std@@QEAA@AEBV01@@Z */
7688 DEFINE_THISCALL_WRAPPER(locale_copy_ctor, 8)
7689 locale* __thiscall locale_copy_ctor(locale *this, const locale *copy)
7690 {
7691     TRACE("(%p %p)\n", this, copy);
7692     this->ptr = copy->ptr;
7693     locale_facet__Incref(&this->ptr->facet);
7694     return this;
7695 }
7696
7697 /* ??0locale@std@@QAE@ABV01@PBDH@Z */
7698 /* ??0locale@std@@QEAA@AEBV01@PEBDH@Z */
7699 DEFINE_THISCALL_WRAPPER(locale_ctor_locale_cstr, 16)
7700 locale* __thiscall locale_ctor_locale_cstr(locale *this, const locale *loc, const char *locname, category cat)
7701 {
7702     FIXME("(%p %p %s %d) stub\n", this, loc, locname, cat);
7703     return NULL;
7704 }
7705
7706 /* ??0locale@std@@QAE@PBDH@Z */
7707 /* ??0locale@std@@QEAA@PEBDH@Z */
7708 DEFINE_THISCALL_WRAPPER(locale_ctor_cstr, 12)
7709 locale* __thiscall locale_ctor_cstr(locale *this, const char *locname, category cat)
7710 {
7711     _Locinfo locinfo;
7712
7713     TRACE("(%p %s %d)\n", this, locname, cat);
7714
7715     this->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
7716     if(!this->ptr) {
7717         ERR("Out of memory\n");
7718         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7719     }
7720     locale__Locimp_ctor(this->ptr);
7721
7722     locale__Init();
7723
7724     _Locinfo_ctor_cat_cstr(&locinfo, cat, locname);
7725     if(!memcmp(basic_string_char_c_str(&locinfo.newlocname), "*", 2)) {
7726         _Locinfo_dtor(&locinfo);
7727         MSVCRT_operator_delete(this->ptr);
7728         throw_exception(EXCEPTION_RUNTIME_ERROR, "bad locale name");
7729     }
7730
7731     locale__Locimp__Makeloc(&locinfo, cat, this->ptr, NULL);
7732     _Locinfo_dtor(&locinfo);
7733
7734     return this;
7735 }
7736
7737 /* ??0locale@std@@QAE@W4_Uninitialized@1@@Z */
7738 /* ??0locale@std@@QEAA@W4_Uninitialized@1@@Z */
7739 DEFINE_THISCALL_WRAPPER(locale_ctor_uninitialized, 8)
7740 locale* __thiscall locale_ctor_uninitialized(locale *this, int uninitialized)
7741 {
7742     TRACE("(%p)\n", this);
7743     this->ptr = NULL;
7744     return this;
7745 }
7746
7747 /* ??0locale@std@@QAE@XZ */
7748 /* ??0locale@std@@QEAA@XZ */
7749 DEFINE_THISCALL_WRAPPER(locale_ctor, 4)
7750 locale* __thiscall locale_ctor(locale *this)
7751 {
7752     TRACE("(%p)\n", this);
7753     this->ptr = locale__Init();
7754     locale_facet__Incref(&this->ptr->facet);
7755     return this;
7756 }
7757
7758 /* ??1locale@std@@QAE@XZ */
7759 /* ??1locale@std@@QEAA@XZ */
7760 DEFINE_THISCALL_WRAPPER(locale_dtor, 4)
7761 void __thiscall locale_dtor(locale *this)
7762 {
7763     TRACE("(%p)\n", this);
7764     if(this->ptr && locale_facet__Decref(&this->ptr->facet)) {
7765         locale__Locimp_dtor(this->ptr);
7766         MSVCRT_operator_delete(this);
7767     }
7768 }
7769
7770 /* ??4locale@std@@QAEAAV01@ABV01@@Z */
7771 /* ??4locale@std@@QEAAAEAV01@AEBV01@@Z */
7772 DEFINE_THISCALL_WRAPPER(locale_operator_assign, 8)
7773 locale* __thiscall locale_operator_assign(locale *this, const locale *loc)
7774 {
7775     FIXME("(%p %p) stub\n", this, loc);
7776     return NULL;
7777 }
7778
7779 /* ??8locale@std@@QBE_NABV01@@Z */
7780 /* ??8locale@std@@QEBA_NAEBV01@@Z */
7781 DEFINE_THISCALL_WRAPPER(locale_operator_equal, 8)
7782 MSVCP_bool __thiscall locale_operator_equal(const locale *this, const locale *loc)
7783 {
7784     FIXME("(%p %p) stub\n", this, loc);
7785     return 0;
7786 }
7787
7788 /* ??9locale@std@@QBE_NABV01@@Z */
7789 /* ??9locale@std@@QEBA_NAEBV01@@Z */
7790 DEFINE_THISCALL_WRAPPER(locale_operator_not_equal, 8)
7791 MSVCP_bool __thiscall locale_operator_not_equal(const locale *this, locale const *loc)
7792 {
7793     FIXME("(%p %p) stub\n", this, loc);
7794     return 0;
7795 }
7796
7797 /* ?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z */
7798 /* ?_Addfac@locale@std@@QEAAAEAV12@PEAVfacet@12@_K1@Z */
7799 DEFINE_THISCALL_WRAPPER(locale__Addfac, 16)
7800 locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_t id, MSVCP_size_t catmask)
7801 {
7802     TRACE("(%p %p %lu %lu)\n", this, facet, id, catmask);
7803
7804     if(this->ptr->facet.refs > 1) {
7805         locale__Locimp *new_ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
7806         if(!new_ptr) {
7807             ERR("Out of memory\n");
7808             throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7809             return NULL;
7810         }
7811         locale__Locimp_copy_ctor(new_ptr, this->ptr);
7812         locale_facet__Decref(&this->ptr->facet);
7813         this->ptr = new_ptr;
7814     }
7815
7816     locale__Locimp__Addfac(this->ptr, facet, id);
7817
7818     if(catmask) {
7819         basic_string_char_dtor(&this->ptr->name);
7820         basic_string_char_ctor_cstr(&this->ptr->name, "*");
7821     }
7822     return this;
7823 }
7824
7825 /* ?_Getfacet@locale@std@@QBEPBVfacet@12@I@Z */
7826 /* ?_Getfacet@locale@std@@QEBAPEBVfacet@12@_K@Z */
7827 static const locale_facet* locale__Getfacet(const locale *this, MSVCP_size_t id)
7828 {
7829     locale_facet *fac;
7830
7831     TRACE("(%p %lu)\n", this, id);
7832
7833     fac = id < this->ptr->facet_cnt ? this->ptr->facetvec[id] : NULL;
7834     if(fac || !this->ptr->transparent)
7835         return fac;
7836
7837     return id < global_locale->facet_cnt ? global_locale->facetvec[id] : NULL;
7838 }
7839
7840 /* ?classic@locale@std@@SAABV12@XZ */
7841 /* ?classic@locale@std@@SAAEBV12@XZ */
7842 const locale* __cdecl locale_classic(void)
7843 {
7844     TRACE("\n");
7845     locale__Init();
7846     return &classic_locale;
7847 }
7848
7849 /* ?empty@locale@std@@SA?AV12@XZ */
7850 locale* __cdecl locale_empty(locale *ret)
7851 {
7852     TRACE("\n");
7853
7854     locale__Init();
7855
7856     ret->ptr = MSVCRT_operator_new(sizeof(locale__Locimp));
7857     if(!ret->ptr) {
7858         ERR("Out of memory\n");
7859         throw_exception(EXCEPTION_BAD_ALLOC, NULL);
7860     }
7861     locale__Locimp_ctor_transparent(ret->ptr, TRUE);
7862     return ret;
7863 }
7864
7865 /* ?name@locale@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
7866 /* ?name@locale@std@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
7867 DEFINE_THISCALL_WRAPPER(locale_name, 8)
7868 basic_string_char* __thiscall locale_name(const locale *this, basic_string_char *ret)
7869 {
7870     TRACE( "(%p)\n", this);
7871     basic_string_char_copy_ctor(ret, &this->ptr->name);
7872     return ret;
7873 }
7874
7875 /* ?global@locale@std@@SA?AV12@ABV12@@Z */
7876 /* ?global@locale@std@@SA?AV12@AEBV12@@Z */
7877 locale* __cdecl locale_global(locale *ret, const locale *loc)
7878 {
7879     _Lockit lock;
7880     int i;
7881
7882     TRACE("(%p %p)\n", loc, ret);
7883
7884     _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
7885     locale_ctor(ret);
7886
7887     if(loc->ptr != global_locale) {
7888         locale_facet__Decref(&global_locale->facet);
7889         global_locale = loc->ptr;
7890         locale_facet__Incref(&global_locale->facet);
7891
7892         for(i=LC_ALL+1; i<=LC_MAX; i++) {
7893             if((global_locale->catmask & (1<<(i-1))) == 0)
7894                 continue;
7895             setlocale(i, basic_string_char_c_str(&global_locale->name));
7896         }
7897     }
7898     _Lockit_dtor(&lock);
7899     return ret;
7900 }
7901
7902 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet@locale@std@@");
7903 DEFINE_RTTI_DATA1(collate_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@D@std@@");
7904 DEFINE_RTTI_DATA1(collate_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@_W@std@@");
7905 DEFINE_RTTI_DATA1(collate_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$collate@G@std@@");
7906 DEFINE_RTTI_DATA1(ctype_base, 0, &locale_facet_rtti_base_descriptor, ".?AUctype_base@std@@");
7907 DEFINE_RTTI_DATA2(ctype_char, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@D@std@@");
7908 DEFINE_RTTI_DATA2(ctype_wchar, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@_W@std@@");
7909 DEFINE_RTTI_DATA2(ctype_short, 0, &ctype_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$ctype@G@std@@");
7910 DEFINE_RTTI_DATA1(codecvt_base, 0, &locale_facet_rtti_base_descriptor, ".?AVcodecvt_base@std@@");
7911 DEFINE_RTTI_DATA2(codecvt_char, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@DDH@std@@");
7912 DEFINE_RTTI_DATA2(codecvt_wchar, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@_WDH@std@@");
7913 DEFINE_RTTI_DATA2(codecvt_short, 0, &codecvt_base_rtti_base_descriptor, &locale_facet_rtti_base_descriptor, ".?AV?$codecvt@GDH@std@@");
7914 DEFINE_RTTI_DATA1(numpunct_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@D@std@@");
7915 DEFINE_RTTI_DATA1(numpunct_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@_W@std@@");
7916 DEFINE_RTTI_DATA1(numpunct_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$numpunct@G@std@@");
7917 DEFINE_RTTI_DATA1(num_get_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@");
7918 DEFINE_RTTI_DATA1(num_get_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@");
7919 DEFINE_RTTI_DATA1(num_get_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@");
7920 DEFINE_RTTI_DATA1(num_put_char, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@");
7921 DEFINE_RTTI_DATA1(num_put_wchar, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@");
7922 DEFINE_RTTI_DATA1(num_put_short, 0, &locale_facet_rtti_base_descriptor, ".?AV?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@");
7923
7924 #ifndef __GNUC__
7925 void __asm_dummy_vtables(void) {
7926 #endif
7927     __ASM_VTABLE(locale_facet,
7928             VTABLE_ADD_FUNC(locale_facet_vector_dtor));
7929     __ASM_VTABLE(collate_char,
7930             VTABLE_ADD_FUNC(collate_char_vector_dtor)
7931             VTABLE_ADD_FUNC(collate_char_do_compare)
7932             VTABLE_ADD_FUNC(collate_char_do_transform)
7933             VTABLE_ADD_FUNC(collate_char_do_hash));
7934     __ASM_VTABLE(collate_wchar,
7935             VTABLE_ADD_FUNC(collate_wchar_vector_dtor)
7936             VTABLE_ADD_FUNC(collate_wchar_do_compare)
7937             VTABLE_ADD_FUNC(collate_wchar_do_transform)
7938             VTABLE_ADD_FUNC(collate_wchar_do_hash));
7939     __ASM_VTABLE(collate_short,
7940             VTABLE_ADD_FUNC(collate_wchar_vector_dtor)
7941             VTABLE_ADD_FUNC(collate_wchar_do_compare)
7942             VTABLE_ADD_FUNC(collate_wchar_do_transform)
7943             VTABLE_ADD_FUNC(collate_wchar_do_hash));
7944     __ASM_VTABLE(ctype_base,
7945             VTABLE_ADD_FUNC(ctype_base_vector_dtor));
7946     __ASM_VTABLE(ctype_char,
7947             VTABLE_ADD_FUNC(ctype_char_vector_dtor)
7948             VTABLE_ADD_FUNC(ctype_char_do_tolower)
7949             VTABLE_ADD_FUNC(ctype_char_do_tolower_ch)
7950             VTABLE_ADD_FUNC(ctype_char_do_toupper)
7951             VTABLE_ADD_FUNC(ctype_char_do_toupper_ch)
7952             VTABLE_ADD_FUNC(ctype_char_do_widen)
7953             VTABLE_ADD_FUNC(ctype_char_do_widen_ch)
7954             VTABLE_ADD_FUNC(ctype_char_do_narrow)
7955             VTABLE_ADD_FUNC(ctype_char_do_narrow_ch));
7956     __ASM_VTABLE(ctype_wchar,
7957             VTABLE_ADD_FUNC(ctype_wchar_vector_dtor)
7958             VTABLE_ADD_FUNC(ctype_wchar_do_is)
7959             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
7960             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
7961             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
7962             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
7963             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
7964             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
7965             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
7966             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
7967             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
7968             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
7969             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch));
7970     __ASM_VTABLE(ctype_short,
7971             VTABLE_ADD_FUNC(ctype_wchar_vector_dtor)
7972             VTABLE_ADD_FUNC(ctype_wchar_do_is)
7973             VTABLE_ADD_FUNC(ctype_wchar_do_is_ch)
7974             VTABLE_ADD_FUNC(ctype_wchar_do_scan_is)
7975             VTABLE_ADD_FUNC(ctype_wchar_do_scan_not)
7976             VTABLE_ADD_FUNC(ctype_wchar_do_tolower)
7977             VTABLE_ADD_FUNC(ctype_wchar_do_tolower_ch)
7978             VTABLE_ADD_FUNC(ctype_wchar_do_toupper)
7979             VTABLE_ADD_FUNC(ctype_wchar_do_toupper_ch)
7980             VTABLE_ADD_FUNC(ctype_wchar_do_widen)
7981             VTABLE_ADD_FUNC(ctype_wchar_do_widen_ch)
7982             VTABLE_ADD_FUNC(ctype_wchar_do_narrow)
7983             VTABLE_ADD_FUNC(ctype_wchar_do_narrow_ch));
7984     __ASM_VTABLE(codecvt_base,
7985             VTABLE_ADD_FUNC(codecvt_base_vector_dtor)
7986             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
7987             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
7988             VTABLE_ADD_FUNC(codecvt_base_do_encoding));
7989     __ASM_VTABLE(codecvt_char,
7990             VTABLE_ADD_FUNC(codecvt_char_vector_dtor)
7991             VTABLE_ADD_FUNC(codecvt_base_do_always_noconv)
7992             VTABLE_ADD_FUNC(codecvt_base_do_max_length)
7993             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
7994             VTABLE_ADD_FUNC(codecvt_char_do_in)
7995             VTABLE_ADD_FUNC(codecvt_char_do_out)
7996             VTABLE_ADD_FUNC(codecvt_char_do_unshift)
7997             VTABLE_ADD_FUNC(codecvt_char_do_length));
7998     __ASM_VTABLE(codecvt_wchar,
7999             VTABLE_ADD_FUNC(codecvt_wchar_vector_dtor)
8000             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8001             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8002             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8003             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8004             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8005             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8006             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8007     __ASM_VTABLE(codecvt_short,
8008             VTABLE_ADD_FUNC(codecvt_wchar_vector_dtor)
8009             VTABLE_ADD_FUNC(codecvt_wchar_do_always_noconv)
8010             VTABLE_ADD_FUNC(codecvt_wchar_do_max_length)
8011             VTABLE_ADD_FUNC(codecvt_base_do_encoding)
8012             VTABLE_ADD_FUNC(codecvt_wchar_do_in)
8013             VTABLE_ADD_FUNC(codecvt_wchar_do_out)
8014             VTABLE_ADD_FUNC(codecvt_wchar_do_unshift)
8015             VTABLE_ADD_FUNC(codecvt_wchar_do_length));
8016     __ASM_VTABLE(numpunct_char,
8017             VTABLE_ADD_FUNC(numpunct_char_vector_dtor)
8018             VTABLE_ADD_FUNC(numpunct_char_do_decimal_point)
8019             VTABLE_ADD_FUNC(numpunct_char_do_thousands_sep)
8020             VTABLE_ADD_FUNC(numpunct_char_do_grouping)
8021             VTABLE_ADD_FUNC(numpunct_char_do_falsename)
8022             VTABLE_ADD_FUNC(numpunct_char_do_truename));
8023     __ASM_VTABLE(numpunct_wchar,
8024             VTABLE_ADD_FUNC(numpunct_wchar_vector_dtor)
8025             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8026             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8027             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8028             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8029             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8030     __ASM_VTABLE(numpunct_short,
8031             VTABLE_ADD_FUNC(numpunct_wchar_vector_dtor)
8032             VTABLE_ADD_FUNC(numpunct_wchar_do_decimal_point)
8033             VTABLE_ADD_FUNC(numpunct_wchar_do_thousands_sep)
8034             VTABLE_ADD_FUNC(numpunct_wchar_do_grouping)
8035             VTABLE_ADD_FUNC(numpunct_wchar_do_falsename)
8036             VTABLE_ADD_FUNC(numpunct_wchar_do_truename));
8037     __ASM_VTABLE(num_get_char,
8038             VTABLE_ADD_FUNC(num_get_char_vector_dtor)
8039             VTABLE_ADD_FUNC(num_get_char_do_get_void)
8040             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8041             VTABLE_ADD_FUNC(num_get_char_do_get_double)
8042             VTABLE_ADD_FUNC(num_get_char_do_get_float)
8043             VTABLE_ADD_FUNC(num_get_char_do_get_uint64)
8044             VTABLE_ADD_FUNC(num_get_char_do_get_int64)
8045             VTABLE_ADD_FUNC(num_get_char_do_get_ulong)
8046             VTABLE_ADD_FUNC(num_get_char_do_get_long)
8047             VTABLE_ADD_FUNC(num_get_char_do_get_uint)
8048             VTABLE_ADD_FUNC(num_get_char_do_get_ushort)
8049             VTABLE_ADD_FUNC(num_get_char_do_get_bool));
8050     __ASM_VTABLE(num_get_short,
8051             VTABLE_ADD_FUNC(num_get_wchar_vector_dtor)
8052             VTABLE_ADD_FUNC(num_get_short_do_get_void)
8053             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8054             VTABLE_ADD_FUNC(num_get_short_do_get_double)
8055             VTABLE_ADD_FUNC(num_get_short_do_get_float)
8056             VTABLE_ADD_FUNC(num_get_short_do_get_uint64)
8057             VTABLE_ADD_FUNC(num_get_short_do_get_int64)
8058             VTABLE_ADD_FUNC(num_get_short_do_get_ulong)
8059             VTABLE_ADD_FUNC(num_get_short_do_get_long)
8060             VTABLE_ADD_FUNC(num_get_short_do_get_uint)
8061             VTABLE_ADD_FUNC(num_get_short_do_get_ushort)
8062             VTABLE_ADD_FUNC(num_get_short_do_get_bool));
8063     __ASM_VTABLE(num_get_wchar,
8064             VTABLE_ADD_FUNC(num_get_wchar_vector_dtor)
8065             VTABLE_ADD_FUNC(num_get_wchar_do_get_void)
8066             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8067             VTABLE_ADD_FUNC(num_get_wchar_do_get_double)
8068             VTABLE_ADD_FUNC(num_get_wchar_do_get_float)
8069             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint64)
8070             VTABLE_ADD_FUNC(num_get_wchar_do_get_int64)
8071             VTABLE_ADD_FUNC(num_get_wchar_do_get_ulong)
8072             VTABLE_ADD_FUNC(num_get_wchar_do_get_long)
8073             VTABLE_ADD_FUNC(num_get_wchar_do_get_uint)
8074             VTABLE_ADD_FUNC(num_get_wchar_do_get_ushort)
8075             VTABLE_ADD_FUNC(num_get_wchar_do_get_bool));
8076     __ASM_VTABLE(num_put_char,
8077             VTABLE_ADD_FUNC(num_put_char_vector_dtor)
8078             VTABLE_ADD_FUNC(num_put_char_do_put_ptr)
8079             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8080             VTABLE_ADD_FUNC(num_put_char_do_put_double)
8081             VTABLE_ADD_FUNC(num_put_char_do_put_uint64)
8082             VTABLE_ADD_FUNC(num_put_char_do_put_int64)
8083             VTABLE_ADD_FUNC(num_put_char_do_put_ulong)
8084             VTABLE_ADD_FUNC(num_put_char_do_put_long)
8085             VTABLE_ADD_FUNC(num_put_char_do_put_bool));
8086     __ASM_VTABLE(num_put_wchar,
8087             VTABLE_ADD_FUNC(num_put_wchar_vector_dtor)
8088             VTABLE_ADD_FUNC(num_put_wchar_do_put_ptr)
8089             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8090             VTABLE_ADD_FUNC(num_put_wchar_do_put_double)
8091             VTABLE_ADD_FUNC(num_put_wchar_do_put_uint64)
8092             VTABLE_ADD_FUNC(num_put_wchar_do_put_int64)
8093             VTABLE_ADD_FUNC(num_put_wchar_do_put_ulong)
8094             VTABLE_ADD_FUNC(num_put_wchar_do_put_long)
8095             VTABLE_ADD_FUNC(num_put_wchar_do_put_bool));
8096     __ASM_VTABLE(num_put_short,
8097             VTABLE_ADD_FUNC(num_put_wchar_vector_dtor)
8098             VTABLE_ADD_FUNC(num_put_short_do_put_ptr)
8099             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8100             VTABLE_ADD_FUNC(num_put_short_do_put_double)
8101             VTABLE_ADD_FUNC(num_put_short_do_put_uint64)
8102             VTABLE_ADD_FUNC(num_put_short_do_put_int64)
8103             VTABLE_ADD_FUNC(num_put_short_do_put_ulong)
8104             VTABLE_ADD_FUNC(num_put_short_do_put_long)
8105             VTABLE_ADD_FUNC(num_put_short_do_put_bool));
8106 #ifndef __GNUC__
8107 }
8108 #endif
8109
8110 void init_locale(void *base)
8111 {
8112 #ifdef __x86_64__
8113     init_locale_facet_rtti(base);
8114     init_collate_char_rtti(base);
8115     init_collate_wchar_rtti(base);
8116     init_collate_short_rtti(base);
8117     init_ctype_base_rtti(base);
8118     init_ctype_char_rtti(base);
8119     init_ctype_wchar_rtti(base);
8120     init_ctype_short_rtti(base);
8121     init_codecvt_base_rtti(base);
8122     init_codecvt_char_rtti(base);
8123     init_codecvt_wchar_rtti(base);
8124     init_codecvt_short_rtti(base);
8125     init_numpunct_char_rtti(base);
8126     init_numpunct_wchar_rtti(base);
8127     init_numpunct_short_rtti(base);
8128     init_num_get_char_rtti(base);
8129     init_num_get_wchar_rtti(base);
8130     init_num_get_short_rtti(base);
8131     init_num_put_char_rtti(base);
8132     init_num_put_wchar_rtti(base);
8133     init_num_put_short_rtti(base);
8134 #endif
8135 }
8136
8137 void free_locale(void)
8138 {
8139     facets_elem *iter, *safe;
8140
8141     if(global_locale) {
8142         locale__Locimp_dtor(global_locale);
8143         locale_dtor(&classic_locale);
8144     }
8145
8146     LIST_FOR_EACH_ENTRY_SAFE(iter, safe, &lazy_facets, facets_elem, entry) {
8147         list_remove(&iter->entry);
8148         if(locale_facet__Decref(iter->fac))
8149             call_locale_facet_vector_dtor(iter->fac, 1);
8150         MSVCRT_operator_delete(iter);
8151     }
8152 }