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