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