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