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