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