winex11: Implement a PutImage entry point in the XRender driver.
[wine] / dlls / msvcp90 / string.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 "stdio.h"
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
30
31 /* _String_iterator<char> and _String_const_iterator<char> class */
32 typedef struct {
33     basic_string_char *bstr;
34     const char *pos;
35 } String_iterator_char;
36 typedef String_iterator_char String_reverse_iterator_char;
37
38 typedef struct {
39     basic_string_wchar *bstr;
40     const wchar_t *pos;
41 } String_iterator_wchar;
42 typedef String_iterator_wchar String_reverse_iterator_wchar;
43
44 /* char_traits<char> */
45 /* ?assign@?$char_traits@D@std@@SAXAADABD@Z */
46 /* ?assign@?$char_traits@D@std@@SAXAEADAEBD@Z */
47 void CDECL MSVCP_char_traits_char_assign(char *ch, const char *assign)
48 {
49     *ch = *assign;
50 }
51
52 /* ?eq@?$char_traits@D@std@@SA_NABD0@Z */
53 /* ?eq@?$char_traits@D@std@@SA_NAEBD0@Z */
54 MSVCP_bool CDECL MSVCP_char_traits_char_eq(const char *ch1, const char *ch2)
55 {
56     return *ch1 == *ch2;
57 }
58
59 /* ?lt@?$char_traits@D@std@@SA_NABD0@Z */
60 /* ?lt@?$char_traits@D@std@@SA_NAEBD0@Z */
61 MSVCP_bool CDECL MSVCP_char_traits_lt(const char *ch1, const char *ch2)
62 {
63     return *ch1 < *ch2;
64 }
65
66 /* ?compare@?$char_traits@D@std@@SAHPBD0I@Z */
67 /* ?compare@?$char_traits@D@std@@SAHPEBD0_K@Z */
68 int CDECL MSVCP_char_traits_char_compare(
69         const char *s1, const char *s2, MSVCP_size_t count)
70 {
71     int ret = memcmp(s1, s2, count);
72     return (ret>0 ? 1 : (ret<0 ? -1 : 0));
73 }
74
75 /* ?length@?$char_traits@D@std@@SAIPBD@Z */
76 /* ?length@?$char_traits@D@std@@SA_KPEBD@Z */
77 MSVCP_size_t CDECL MSVCP_char_traits_char_length(const char *str)
78 {
79     return strlen(str);
80 }
81
82 /* ?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
83 /* ?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
84 char* CDECL MSVCP_char_traits_char__Copy_s(char *dest,
85         MSVCP_size_t size, const char *src, MSVCP_size_t count)
86 {
87     if(!dest || !src || size<count) {
88         if(dest && size)
89             dest[0] = '\0';
90         _invalid_parameter(NULL, NULL, NULL, 0, 0);
91         return dest;
92     }
93
94     return memcpy(dest, src, count);
95 }
96
97 /* ?copy@?$char_traits@D@std@@SAPADPADPBDI@Z */
98 /* ?copy@?$char_traits@D@std@@SAPEADPEADPEBD_K@Z */
99 char* CDECL MSVCP_char_traits_char_copy(
100         char *dest, const char *src, MSVCP_size_t count)
101 {
102     return MSVCP_char_traits_char__Copy_s(dest, count, src, count);
103 }
104
105 /* ?find@?$char_traits@D@std@@SAPBDPBDIABD@Z */
106 /* ?find@?$char_traits@D@std@@SAPEBDPEBD_KAEBD@Z */
107 const char * CDECL MSVCP_char_traits_char_find(
108         const char *str, MSVCP_size_t range, const char *c)
109 {
110     return memchr(str, *c, range);
111 }
112
113 /* ?_Move_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
114 /* ?_Move_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
115 char* CDECL MSVCP_char_traits_char__Move_s(char *dest,
116         MSVCP_size_t size, const char *src, MSVCP_size_t count)
117 {
118     if(!dest || !src || size<count) {
119         if(dest && size)
120             dest[0] = '\0';
121         _invalid_parameter(NULL, NULL, NULL, 0, 0);
122         return dest;
123     }
124
125     return memmove(dest, src, count);
126 }
127
128 /* ?move@?$char_traits@D@std@@SAPADPADPBDI@Z */
129 /* ?move@?$char_traits@D@std@@SAPEADPEADPEBD_K@Z */
130 char* CDECL MSVCP_char_traits_char_move(
131         char *dest, const char *src, MSVCP_size_t count)
132 {
133     return MSVCP_char_traits_char__Move_s(dest, count, src, count);
134 }
135
136 /* ?assign@?$char_traits@D@std@@SAPADPADID@Z */
137 /* ?assign@?$char_traits@D@std@@SAPEADPEAD_KD@Z */
138 char* CDECL MSVCP_char_traits_char_assignn(char *str, MSVCP_size_t num, char c)
139 {
140     return memset(str, c, num);
141 }
142
143 /* ?to_char_type@?$char_traits@D@std@@SADABH@Z */
144 /* ?to_char_type@?$char_traits@D@std@@SADAEBH@Z */
145 char CDECL MSVCP_char_traits_char_to_char_type(const int *i)
146 {
147     return (char)*i;
148 }
149
150 /* ?to_int_type@?$char_traits@D@std@@SAHABD@Z */
151 /* ?to_int_type@?$char_traits@D@std@@SAHAEBD@Z */
152 int CDECL MSVCP_char_traits_char_to_int_type(const char *ch)
153 {
154     return (int)*ch;
155 }
156
157 /* ?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z */
158 /* ?eq_int_type@?$char_traits@D@std@@SA_NAEBH0@Z */
159 MSVCP_bool CDECL MSVCP_char_traits_char_eq_int_type(const int *i1, const int *i2)
160 {
161     return *i1 == *i2;
162 }
163
164 /* ?eof@?$char_traits@D@std@@SAHXZ */
165 int CDECL MSVCP_char_traits_char_eof(void)
166 {
167     return EOF;
168 }
169
170 /* ?not_eof@?$char_traits@D@std@@SAHABH@Z */
171 /* ?not_eof@?$char_traits@D@std@@SAHAEBH@Z */
172 int CDECL MSVCP_char_traits_char_not_eof(int *in)
173 {
174     return (*in==EOF ? !EOF : *in);
175 }
176
177
178 /* char_traits<wchar_t> */
179 /* ?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z */
180 /* ?assign@?$char_traits@_W@std@@SAXAEA_WAEB_W@Z */
181 void CDECL MSVCP_char_traits_wchar_assign(wchar_t *ch,
182         const wchar_t *assign)
183 {
184     *ch = *assign;
185 }
186
187 /* ?eq@?$char_traits@_W@std@@SA_NAB_W0@Z */
188 /* ?eq@?$char_traits@_W@std@@SA_NAEB_W0@Z */
189 MSVCP_bool CDECL MSVCP_char_traits_wchar_eq(wchar_t *ch1, wchar_t *ch2)
190 {
191     return *ch1 == *ch2;
192 }
193
194 /* ?lt@?$char_traits@_W@std@@SA_NAB_W0@Z */
195 /* ?lt@?$char_traits@_W@std@@SA_NAEB_W0@Z */
196 MSVCP_bool CDECL MSVCP_char_traits_wchar_lt(const wchar_t *ch1,
197         const wchar_t *ch2)
198 {
199     return *ch1 < *ch2;
200 }
201
202 /* ?compare@?$char_traits@_W@std@@SAHPB_W0I@Z */
203 /* ?compare@?$char_traits@_W@std@@SAHPEB_W0_K@Z */
204 int CDECL MSVCP_char_traits_wchar_compare(const wchar_t *s1,
205         const wchar_t *s2, MSVCP_size_t count)
206 {
207     int ret = memcmp(s1, s2, sizeof(wchar_t[count]));
208     return (ret>0 ? 1 : (ret<0 ? -1 : 0));
209 }
210
211 /* ?length@?$char_traits@_W@std@@SAIPB_W@Z */
212 /* ?length@?$char_traits@_W@std@@SA_KPEB_W@Z */
213 MSVCP_size_t CDECL MSVCP_char_traits_wchar_length(const wchar_t *str)
214 {
215     return wcslen((WCHAR*)str);
216 }
217
218 /* ?_Copy_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
219 /* ?_Copy_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
220 wchar_t* CDECL MSVCP_char_traits_wchar__Copy_s(wchar_t *dest,
221         MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
222 {
223     if(!dest || !src || size<count) {
224         if(dest && size)
225             dest[0] = '\0';
226         _invalid_parameter(NULL, NULL, NULL, 0, 0);
227         return dest;
228     }
229
230     return memcpy(dest, src, sizeof(wchar_t[count]));
231 }
232
233 /* ?copy@?$char_traits@_W@std@@SAPA_WPA_WPB_WI@Z */
234 /* ?copy@?$char_traits@_W@std@@SAPEA_WPEA_WPEB_W_K@Z */
235 wchar_t* CDECL MSVCP_char_traits_wchar_copy(wchar_t *dest,
236         const wchar_t *src, MSVCP_size_t count)
237 {
238     return MSVCP_char_traits_wchar__Copy_s(dest, count, src, count);
239 }
240
241 /* ?find@?$char_traits@_W@std@@SAPB_WPB_WIAB_W@Z */
242 /* ?find@?$char_traits@_W@std@@SAPEB_WPEB_W_KAEB_W@Z */
243 const wchar_t* CDECL MSVCP_char_traits_wchar_find(
244         const wchar_t *str, MSVCP_size_t range, const wchar_t *c)
245 {
246     MSVCP_size_t i=0;
247
248     for(i=0; i<range; i++)
249         if(str[i] == *c)
250             return str+i;
251
252     return NULL;
253 }
254
255 /* ?_Move_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
256 /* ?_Move_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
257 wchar_t* CDECL MSVCP_char_traits_wchar__Move_s(wchar_t *dest,
258         MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
259 {
260     if(!dest || !src || size<count) {
261         if(dest && size)
262             dest[0] = '\0';
263         _invalid_parameter(NULL, NULL, NULL, 0, 0);
264         return dest;
265     }
266
267     return memmove(dest, src, sizeof(WCHAR[count]));
268 }
269
270 /* ?move@?$char_traits@_W@std@@SAPA_WPA_WPB_WI@Z */
271 /* ?move@?$char_traits@_W@std@@SAPEA_WPEA_WPEB_W_K@Z */
272 wchar_t* CDECL MSVCP_char_traits_wchar_move(wchar_t *dest,
273         const wchar_t *src, MSVCP_size_t count)
274 {
275     return MSVCP_char_traits_wchar__Move_s(dest, count, src, count);
276 }
277
278 /* ?assign@?$char_traits@_W@std@@SAPA_WPA_WI_W@Z */
279 /* ?assign@?$char_traits@_W@std@@SAPEA_WPEA_W_K_W@Z */
280 wchar_t* CDECL MSVCP_char_traits_wchar_assignn(wchar_t *str,
281         MSVCP_size_t num, wchar_t c)
282 {
283     MSVCP_size_t i;
284
285     for(i=0; i<num; i++)
286         str[i] = c;
287
288     return str;
289 }
290
291 /* ?to_char_type@?$char_traits@_W@std@@SA_WABG@Z */
292 /* ?to_char_type@?$char_traits@_W@std@@SA_WAEBG@Z */
293 wchar_t CDECL MSVCP_char_traits_wchar_to_char_type(const unsigned short *i)
294 {
295     return *i;
296 }
297
298 /* ?to_int_type@?$char_traits@_W@std@@SAGAB_W@Z */
299 /* ?to_int_type@?$char_traits@_W@std@@SAGAEB_W@Z */
300 unsigned short CDECL MSVCP_char_traits_wchar_to_int_type(const wchar_t *ch)
301 {
302     return *ch;
303 }
304
305 /* ?eq_int_type@?$char_traits@_W@std@@SA_NABG0@Z */
306 /* ?eq_int_type@?$char_traits@_W@std@@SA_NAEBG0@Z */
307 MSVCP_bool CDECL MSVCP_char_traits_wchar_eq_int_tpe(const unsigned short *i1,
308         const unsigned short *i2)
309 {
310     return *i1 == *i2;
311 }
312
313 /* ?eof@?$char_traits@_W@std@@SAGXZ */
314 unsigned short CDECL MSVCP_char_traits_wchar_eof(void)
315 {
316     return WEOF;
317 }
318
319 /* ?not_eof@?$char_traits@_W@std@@SAGABG@Z */
320 /* ?not_eof@?$char_traits@_W@std@@SAGAEBG@Z */
321 unsigned short CDECL MSVCP_char_traits_wchar_not_eof(const unsigned short *in)
322 {
323     return (*in==WEOF ? !WEOF : *in);
324 }
325
326
327 /* char_traits<unsigned short> */
328 /* ?assign@?$char_traits@G@std@@SAXAAGABG@Z */
329 /* ?assign@?$char_traits@G@std@@SAXAEAGAEBG@Z */
330 void CDECL MSVCP_char_traits_short_assign(unsigned short *ch,
331         const unsigned short *assign)
332 {
333     *ch = *assign;
334 }
335
336 /* ?eq@?$char_traits@G@std@@SA_NABG0@Z */
337 /* ?eq@?$char_traits@G@std@@SA_NAEBG0@Z */
338 MSVCP_bool CDECL MSVCP_char_traits_short_eq(const unsigned short *ch1,
339         const unsigned short *ch2)
340 {
341     return *ch1 == *ch2;
342 }
343
344 /* ?lt@?$char_traits@G@std@@SA_NABG0@Z */
345 /* ?lt@?$char_traits@G@std@@SA_NAEBG0@Z */
346 MSVCP_bool CDECL MSVCP_char_traits_short_lt(const unsigned short *ch1,
347         const unsigned short *ch2)
348 {
349     return *ch1 < *ch2;
350 }
351
352 /* ?compare@?$char_traits@G@std@@SAHPBG0I@Z */
353 /* ?compare@?$char_traits@G@std@@SAHPEBG0_K@Z */
354 int CDECL MSVCP_char_traits_short_compare(const unsigned short *s1,
355         const unsigned short *s2, MSVCP_size_t count)
356 {
357     MSVCP_size_t i;
358
359     for(i=0; i<count; i++)
360         if(s1[i] != s2[i])
361             return (s1[i] < s2[i] ? -1 : 1);
362
363     return 0;
364 }
365
366 /* ?length@?$char_traits@G@std@@SAIPBG@Z */
367 /* ?length@?$char_traits@G@std@@SA_KPEBG@Z */
368 MSVCP_size_t CDECL MSVCP_char_traits_short_length(const unsigned short *str)
369 {
370     MSVCP_size_t len;
371
372     for(len=0; str[len]; len++);
373
374     return len;
375 }
376
377 /* ?_Copy_s@?$char_traits@G@std@@SAPAGPAGIPBGI@Z */
378 /* ?_Copy_s@?$char_traits@G@std@@SAPEAGPEAG_KPEBG1@Z */
379 unsigned short * CDECL MSVCP_char_traits_short__Copy_s(unsigned short *dest,
380         MSVCP_size_t size, const unsigned short *src, MSVCP_size_t count)
381 {
382     if(size<count) {
383         _invalid_parameter(NULL, NULL, NULL, 0, 0);
384         return dest;
385     }
386
387     return memcpy(dest, src, sizeof(unsigned short[count]));
388 }
389
390 /* ?copy@?$char_traits@G@std@@SAPAGPAGPBGI@Z */
391 /* ?copy@?$char_traits@G@std@@SAPEAGPEAGPEBG_K@Z */
392 unsigned short* CDECL MSVCP_char_traits_short_copy(unsigned short *dest,
393         const unsigned short *src, MSVCP_size_t count)
394 {
395     return MSVCP_char_traits_short__Copy_s(dest, count, src, count);
396 }
397
398 /* ?find@?$char_traits@G@std@@SAPBGPBGIABG@Z */
399 /* ?find@?$char_traits@G@std@@SAPEBGPEBG_KAEBG@Z */
400 const unsigned short* CDECL MSVCP_char_traits_short_find(
401         const unsigned short *str, MSVCP_size_t range, const unsigned short *c)
402 {
403     MSVCP_size_t i;
404
405     for(i=0; i<range; i++)
406         if(str[i] == *c)
407             return str+i;
408
409     return NULL;
410 }
411
412 /* ?_Move_s@?$char_traits@G@std@@SAPAGPAGIPBGI@Z */
413 /* ?_Move_s@?$char_traits@G@std@@SAPEAGPEAG_KPEBG1@Z */
414 unsigned short* CDECL MSVCP_char_traits_short__Move_s(unsigned short *dest,
415         MSVCP_size_t size, const unsigned short *src, MSVCP_size_t count)
416 {
417     if(size<count) {
418         _invalid_parameter(NULL, NULL, NULL, 0, 0);
419         return dest;
420     }
421
422     return memmove(dest, src, sizeof(unsigned short[count]));
423 }
424
425 /* ?move@?$char_traits@G@std@@SAPAGPAGPBGI@Z */
426 /* ?move@?$char_traits@G@std@@SAPEAGPEAGPEBG_K@Z */
427 unsigned short* CDECL MSVCP_char_traits_short_move(unsigned short *dest,
428         const unsigned short *src, MSVCP_size_t count)
429 {
430     return MSVCP_char_traits_short__Move_s(dest, count, src, count);
431 }
432
433 /* ?assign@?$char_traits@G@std@@SAPAGPAGIG@Z */
434 /* ?assign@?$char_traits@G@std@@SAPEAGPEAG_KG@Z */
435 unsigned short* CDECL MSVCP_char_traits_short_assignn(unsigned short *str,
436         MSVCP_size_t num, unsigned short c)
437 {
438     MSVCP_size_t i;
439
440     for(i=0; i<num; i++)
441         str[i] = c;
442
443     return str;
444 }
445
446 /* ?to_char_type@?$char_traits@G@std@@SAGABG@Z */
447 /* ?to_char_type@?$char_traits@G@std@@SAGAEBG@Z */
448 unsigned short CDECL MSVCP_char_traits_short_to_char_type(const unsigned short *i)
449 {
450     return *i;
451 }
452
453 /* ?to_int_type@?$char_traits@G@std@@SAGABG@Z */
454 /* ?to_int_type@?$char_traits@G@std@@SAGAEBG@Z */
455 unsigned short CDECL MSVCP_char_traits_short_to_int_type(const unsigned short *ch)
456 {
457     return *ch;
458 }
459
460 /* ?eq_int_type@?$char_traits@G@std@@SA_NABG0@Z */
461 /* ?eq_int_type@?$char_traits@G@std@@SA_NAEBG0@Z */
462 MSVCP_bool CDECL MSVCP_char_traits_short_eq_int_type(unsigned short *i1,
463         unsigned short *i2)
464 {
465     return *i1 == *i2;
466 }
467
468 /* ?eof@?$char_traits@G@std@@SAGXZ */
469 unsigned short CDECL MSVCP_char_traits_short_eof(void)
470 {
471     return -1;
472 }
473
474 /* ?not_eof@?$char_traits@G@std@@SAGABG@Z */
475 /* ?not_eof@?$char_traits@G@std@@SAGAEBG@Z */
476 unsigned short CDECL MSVCP_char_traits_short_not_eof(const unsigned short *in)
477 {
478     return (*in==(unsigned short)-1 ? 0 : *in);
479 }
480
481
482 /* _String_base */
483 /* ?_Xlen@_String_base@std@@SAXXZ */
484 void  CDECL MSVCP__String_base_Xlen(void)
485 {
486     static const char msg[] = "string too long";
487
488     TRACE("\n");
489     throw_exception(EXCEPTION_LENGTH_ERROR, msg);
490 }
491
492 /* ?_Xran@_String_base@std@@SAXXZ */
493 void CDECL MSVCP__String_base_Xran(void)
494 {
495     static const char msg[] = "invalid string position";
496
497     TRACE("\n");
498     throw_exception(EXCEPTION_OUT_OF_RANGE, msg);
499 }
500
501 /* ?_Xinvarg@_String_base@std@@SAXXZ */
502 void CDECL MSVCP__String_base_Xinvarg(void)
503 {
504     static const char msg[] = "invalid string argument";
505
506     TRACE("\n");
507     throw_exception(EXCEPTION_INVALID_ARGUMENT, msg);
508 }
509
510
511 /* basic_string<char, char_traits<char>, allocator<char>> */
512 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB */
513 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2_KB */
514 const MSVCP_size_t MSVCP_basic_string_char_npos = -1;
515
516 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEPADXZ */
517 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAPEADXZ */
518 DEFINE_THISCALL_WRAPPER(basic_string_char_ptr, 4)
519 char* __thiscall basic_string_char_ptr(basic_string_char *this)
520 {
521     if(this->res == BUF_SIZE_CHAR-1)
522         return this->data.buf;
523     return this->data.ptr;
524 }
525
526 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IBEPBDXZ */
527 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEBAPEBDXZ */
528 DEFINE_THISCALL_WRAPPER(basic_string_char_const_ptr, 4)
529 const char* __thiscall basic_string_char_const_ptr(const basic_string_char *this)
530 {
531     if(this->res == BUF_SIZE_CHAR-1)
532         return this->data.buf;
533     return this->data.ptr;
534 }
535
536 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEXI@Z */
537 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_K@Z */
538 DEFINE_THISCALL_WRAPPER(basic_string_char_eos, 8)
539 void __thiscall basic_string_char_eos(basic_string_char *this, MSVCP_size_t len)
540 {
541     static const char nullbyte = '\0';
542
543     this->size = len;
544     MSVCP_char_traits_char_assign(basic_string_char_ptr(this)+len, &nullbyte);
545 }
546
547 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NPBD@Z */
548 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_NPEBD@Z */
549 DEFINE_THISCALL_WRAPPER(basic_string_char_inside, 8)
550 MSVCP_bool __thiscall basic_string_char_inside(
551         basic_string_char *this, const char *ptr)
552 {
553     char *cstr = basic_string_char_ptr(this);
554
555     return (ptr<cstr || ptr>=cstr+this->size) ? FALSE : TRUE;
556 }
557
558 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEX_NI@Z */
559 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_N_K@Z */
560 DEFINE_THISCALL_WRAPPER(basic_string_char_tidy, 12)
561 void __thiscall basic_string_char_tidy(basic_string_char *this,
562         MSVCP_bool built, MSVCP_size_t new_size)
563 {
564     if(built && BUF_SIZE_CHAR<=this->res) {
565         char *ptr = this->data.ptr;
566
567         if(new_size > 0)
568             MSVCP_char_traits_char__Copy_s(this->data.buf, BUF_SIZE_CHAR, ptr, new_size);
569         MSVCP_allocator_char_deallocate(this->allocator, ptr, this->res+1);
570     }
571
572     this->res = BUF_SIZE_CHAR-1;
573     basic_string_char_eos(this, new_size);
574 }
575
576 /* Exported only from msvcp60/70 */
577 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z */
578 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAAX_N@Z */
579 DEFINE_THISCALL_WRAPPER(basic_string_char_tidy_built, 8)
580 void __thiscall basic_string_char_tidy_built(basic_string_char *this, MSVCP_bool built)
581 {
582     basic_string_char_tidy(this, built, 0);
583 }
584
585 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NI_N@Z */
586 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_N_K_N@Z */
587 DEFINE_THISCALL_WRAPPER(basic_string_char_grow, 12)
588 MSVCP_bool __thiscall basic_string_char_grow(
589         basic_string_char *this, MSVCP_size_t new_size, MSVCP_bool trim)
590 {
591     if(this->res < new_size) {
592         MSVCP_size_t new_res = new_size, len = this->size;
593         char *ptr;
594
595         new_res |= 0xf;
596
597         if(new_res/3 < this->res/2)
598             new_res = this->res + this->res/2;
599
600         ptr = MSVCP_allocator_char_allocate(this->allocator, new_res);
601         if(!ptr)
602             ptr = MSVCP_allocator_char_allocate(this->allocator, new_size+1);
603         else
604             new_size = new_res;
605         if(!ptr) {
606             ERR("Out of memory\n");
607             basic_string_char_tidy(this, TRUE, 0);
608             return FALSE;
609         }
610
611         MSVCP_char_traits_char__Copy_s(ptr, new_size,
612                 basic_string_char_ptr(this), this->size);
613         basic_string_char_tidy(this, TRUE, 0);
614         this->data.ptr = ptr;
615         this->res = new_size;
616         basic_string_char_eos(this, len);
617     } else if(trim && new_size < BUF_SIZE_CHAR)
618         basic_string_char_tidy(this, TRUE,
619                 new_size<this->size ? new_size : this->size);
620     else if(new_size == 0)
621         basic_string_char_eos(this, 0);
622
623     return (new_size>0);
624 }
625
626 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z */
627 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z */
628 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_erase, 12)
629 basic_string_char* __thiscall MSVCP_basic_string_char_erase(
630         basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t len)
631 {
632     TRACE("%p %lu %lu\n", this, pos, len);
633
634     if(pos > this->size) {
635         MSVCP__String_base_Xran();
636         return NULL;
637     }
638
639     if(len > this->size-pos)
640         len = this->size-pos;
641
642     if(len) {
643         MSVCP_char_traits_char__Move_s(basic_string_char_ptr(this)+pos,
644                 this->res-pos, basic_string_char_ptr(this)+pos+len,
645                 this->size-pos-len);
646         basic_string_char_eos(this, this->size-len);
647     }
648
649     return this;
650 }
651
652 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z */
653 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
654 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_substr, 16)
655 basic_string_char* __thiscall MSVCP_basic_string_char_assign_substr(
656         basic_string_char *this, const basic_string_char *assign,
657         MSVCP_size_t pos, MSVCP_size_t len)
658 {
659     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
660
661     if(assign->size < pos) {
662         MSVCP__String_base_Xran();
663         return NULL;
664     }
665
666     if(len > assign->size-pos)
667         len = assign->size-pos;
668
669     if(this == assign) {
670         MSVCP_basic_string_char_erase(this, pos+len, MSVCP_basic_string_char_npos);
671         MSVCP_basic_string_char_erase(this, 0, pos);
672     } else if(basic_string_char_grow(this, len, FALSE)) {
673         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
674                 this->res, basic_string_char_const_ptr(assign)+pos, len);
675         basic_string_char_eos(this, len);
676     }
677
678     return this;
679 }
680
681 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z */
682 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z */
683 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z */
684 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@AEBV01@@Z */
685 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign, 8)
686 basic_string_char* __thiscall MSVCP_basic_string_char_assign(
687         basic_string_char *this, const basic_string_char *assign)
688 {
689     return MSVCP_basic_string_char_assign_substr(this, assign,
690             0, MSVCP_basic_string_char_npos);
691 }
692
693 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z */
694 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z */
695 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_cstr_len, 12)
696 basic_string_char* __thiscall MSVCP_basic_string_char_assign_cstr_len(
697         basic_string_char *this, const char *str, MSVCP_size_t len)
698 {
699     TRACE("%p %s %lu\n", this, debugstr_a(str), len);
700
701     if(basic_string_char_inside(this, str))
702         return MSVCP_basic_string_char_assign_substr(this, this,
703                 str-basic_string_char_ptr(this), len);
704     else if(basic_string_char_grow(this, len, FALSE)) {
705         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
706                 this->res, str, len);
707         basic_string_char_eos(this, len);
708     }
709
710     return this;
711 }
712
713 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@D@Z */
714 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@D@Z */
715 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_ch, 8)
716 basic_string_char* __thiscall MSVCP_basic_string_char_assign_ch(
717         basic_string_char *this, char ch)
718 {
719     return MSVCP_basic_string_char_assign_cstr_len(this, &ch, 1);
720 }
721
722 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z */
723 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD@Z */
724 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z */
725 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@PEBD@Z */
726 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_cstr, 8)
727 basic_string_char* __thiscall MSVCP_basic_string_char_assign_cstr(
728         basic_string_char *this, const char *str)
729 {
730     return MSVCP_basic_string_char_assign_cstr_len(this, str,
731             MSVCP_char_traits_char_length(str));
732 }
733
734 /* ?_Chassign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEXIID@Z */
735 /* ?_Chassign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_K0D@Z */
736 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_Chassign, 16)
737 void __thiscall MSVCP_basic_string_char_Chassign(basic_string_char *this,
738         MSVCP_size_t off, MSVCP_size_t count, char ch)
739 {
740     TRACE("%p %lu %lu %c\n", this, off, count, ch);
741     MSVCP_char_traits_char_assignn(basic_string_char_ptr(this)+off, count, ch);
742 }
743
744 /* ?_Copy_s@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPADIII@Z */
745 /* ?_Copy_s@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEAD_K11@Z */
746 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_Copy_s, 20)
747 MSVCP_size_t __thiscall MSVCP_basic_string_char_Copy_s(const basic_string_char *this,
748         char *dest, MSVCP_size_t size, MSVCP_size_t off, MSVCP_size_t count)
749 {
750     TRACE("%p %p %lu %lu %lu\n", this, dest, size, off, count);
751
752     if(this->size < off)
753         MSVCP__String_base_Xran();
754
755     if(count > this->size-off)
756         count = this->size-off;
757
758     MSVCP_char_traits_char__Copy_s(dest, size,
759             basic_string_char_const_ptr(this)+off, count);
760     return count;
761 }
762
763 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
764 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
765 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
766 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
767 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_c_str, 4)
768 const char* __thiscall MSVCP_basic_string_char_c_str(basic_string_char *this)
769 {
770     TRACE("%p\n", this);
771     return basic_string_char_const_ptr(this);
772 }
773
774 /* ?capacity@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
775 /* ?capacity@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
776 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_capacity, 4)
777 MSVCP_size_t __thiscall MSVCP_basic_string_char_capacity(basic_string_char *this)
778 {
779     TRACE("%p\n", this);
780     return this->res;
781 }
782
783 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
784 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
785 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor, 4)
786 basic_string_char* __thiscall MSVCP_basic_string_char_ctor(basic_string_char *this)
787 {
788     TRACE("%p\n", this);
789
790     basic_string_char_tidy(this, FALSE, 0);
791     return this;
792 }
793
794 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z */
795 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@@Z */
796 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_copy_ctor, 8)
797 basic_string_char* __thiscall MSVCP_basic_string_char_copy_ctor(
798     basic_string_char *this, const basic_string_char *copy)
799 {
800     TRACE("%p %p\n", this, copy);
801
802     basic_string_char_tidy(this, FALSE, 0);
803     MSVCP_basic_string_char_assign(this, copy);
804     return this;
805 }
806
807 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z */
808 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z */
809 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor_cstr, 8)
810 basic_string_char* __thiscall MSVCP_basic_string_char_ctor_cstr(
811         basic_string_char *this, const char *str)
812 {
813     TRACE("%p %s\n", this, debugstr_a(str));
814
815     basic_string_char_tidy(this, FALSE, 0);
816     MSVCP_basic_string_char_assign_cstr(this, str);
817     return this;
818 }
819
820 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBDI@Z */
821 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD_K@Z */
822 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor_cstr_len, 12)
823 basic_string_char* __thiscall MSVCP_basic_string_char_ctor_cstr_len(
824         basic_string_char *this, const char *str, MSVCP_size_t len)
825 {
826     TRACE("%p %s %ld\n", this, str, len);
827
828     basic_string_char_tidy(this, FALSE, 0);
829     MSVCP_basic_string_char_assign_cstr_len(this, str, len);
830     return this;
831 }
832
833 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@II@Z */
834 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@_K1@Z */
835 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor_substr, 16)
836 basic_string_char* __thiscall MSVCP_basic_string_char_ctor_substr(
837         basic_string_char *this, const basic_string_char *assign,
838         MSVCP_size_t pos, MSVCP_size_t len)
839 {
840     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
841
842     basic_string_char_tidy(this, FALSE, 0);
843     MSVCP_basic_string_char_assign_substr(this, assign, pos, len);
844     return this;
845 }
846
847 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV?$allocator@D@1@@Z */
848 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV?$allocator@D@1@@Z */
849 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor_alloc, 8)
850 basic_string_char* __thiscall MSVCP_basic_string_char_ctor_alloc(
851         basic_string_char *this, const void *alloc)
852 {
853     TRACE("%p %p\n", this, alloc);
854
855     basic_string_char_tidy(this, FALSE, 0);
856     return this;
857 }
858
859 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
860 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
861 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_dtor, 4)
862 void __thiscall MSVCP_basic_string_char_dtor(basic_string_char *this)
863 {
864     TRACE("%p\n", this);
865     basic_string_char_tidy(this, TRUE, 0);
866 }
867
868 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
869 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
870 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
871 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
872 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_length, 4)
873 MSVCP_size_t __thiscall MSVCP_basic_string_char_length(basic_string_char *this)
874 {
875     TRACE("%p\n", this);
876     return this->size;
877 }
878
879 /* ?empty@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE_NXZ */
880 /* ?empty@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_NXZ */
881 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_empty, 4)
882 MSVCP_bool __thiscall MSVCP_basic_string_char_empty(basic_string_char *this)
883 {
884     TRACE("%p\n", this);
885     return this->size == 0;
886 }
887
888 /* ?swap@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXAAV12@@Z */
889 /* ?swap@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXAEAV12@@Z */
890 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_swap, 8)
891 void __thiscall MSVCP_basic_string_char_swap(basic_string_char *this, basic_string_char *str)
892 {
893     if(this != str) {
894         char tmp[sizeof(this->data)];
895         const MSVCP_size_t size = this->size;
896         const MSVCP_size_t res = this->res;
897
898         memcpy(tmp, this->data.buf, sizeof(this->data));
899         memcpy(this->data.buf, str->data.buf, sizeof(this->data));
900         memcpy(str->data.buf, tmp, sizeof(this->data));
901
902         this->size = str->size;
903         this->res = str->res;
904
905         str->size = size;
906         str->res = res;
907     }
908 }
909
910 /* ?substr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV12@II@Z */
911 /* ?substr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV12@_K0@Z */
912 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_char_substr, 12)
913 basic_string_char __thiscall MSVCP_basic_string_char_substr(
914         basic_string_char *this, MSVCP_size_t off, MSVCP_size_t len)
915 {
916     basic_string_char ret = { 0 };
917     TRACE("%p %lu %lu\n", this, off, len);
918
919     MSVCP_basic_string_char_ctor_substr(&ret, this, off, len);
920     return ret;
921 }
922
923 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z */
924 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
925 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_substr, 16)
926 basic_string_char* __thiscall MSVCP_basic_string_char_append_substr(basic_string_char *this,
927         const basic_string_char *append, MSVCP_size_t offset, MSVCP_size_t count)
928 {
929     TRACE("%p %p %lu %lu\n", this, append, offset, count);
930
931     if(append->size < offset)
932         MSVCP__String_base_Xran();
933
934     if(count > append->size-offset)
935         count = append->size-offset;
936
937     if(MSVCP_basic_string_char_npos-this->size<=count || this->size+count<this->size)
938         MSVCP__String_base_Xlen();
939
940     if(basic_string_char_grow(this, this->size+count, FALSE)) {
941         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this)+this->size,
942                 this->res-this->size, basic_string_char_const_ptr(append)+offset, count);
943         basic_string_char_eos(this, this->size+count);
944     }
945
946     return this;
947 }
948
949 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z */
950 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z */
951 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z */
952 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@AEBV01@@Z */
953 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append, 8)
954 basic_string_char* __thiscall MSVCP_basic_string_char_append(
955         basic_string_char *this, const basic_string_char *append)
956 {
957     return MSVCP_basic_string_char_append_substr(this, append,
958             0, MSVCP_basic_string_char_npos);
959 }
960
961 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z */
962 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z */
963 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_cstr_len, 12)
964 basic_string_char* __thiscall MSVCP_basic_string_char_append_cstr_len(
965         basic_string_char *this, const char *append, MSVCP_size_t count)
966 {
967     TRACE("%p %s %lu\n", this, append, count);
968
969     if(basic_string_char_inside(this, append))
970         return MSVCP_basic_string_char_append_substr(this, this,
971                 append-basic_string_char_ptr(this), count);
972
973     if(MSVCP_basic_string_char_npos-this->size<=count || this->size+count<this->size)
974         MSVCP__String_base_Xlen();
975
976     if(basic_string_char_grow(this, this->size+count, FALSE)) {
977         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this)+this->size,
978                 this->res-this->size, append, count);
979         basic_string_char_eos(this, this->size+count);
980     }
981
982     return this;
983 }
984
985 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z */
986 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD@Z */
987 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z */
988 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@PEBD@Z */
989 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_cstr, 8)
990 basic_string_char* __thiscall MSVCP_basic_string_char_append_cstr(
991         basic_string_char *this, const char *append)
992 {
993     return MSVCP_basic_string_char_append_cstr_len(this, append,
994             MSVCP_char_traits_char_length(append));
995 }
996
997 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD0@Z */
998 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD0@Z */
999 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_beg_end, 12)
1000 basic_string_char* __thiscall MSVCP_basic_string_char_append_beg_end(
1001         basic_string_char *this, const char *beg, const char *end)
1002 {
1003     return MSVCP_basic_string_char_append_cstr_len(this, beg, end-beg);
1004 }
1005
1006 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z */
1007 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z */
1008 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_iter, 20)
1009 basic_string_char* __thiscall MSVCP_basic_string_char_append_iter(
1010         basic_string_char *this, String_iterator_char beg, String_iterator_char end)
1011 {
1012     return MSVCP_basic_string_char_append_cstr_len(this, beg.pos, end.pos-beg.pos+1);
1013 }
1014
1015 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ID@Z */
1016 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_KD@Z */
1017 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_len_ch, 12)
1018 basic_string_char* __thiscall MSVCP_basic_string_char_append_len_ch(
1019         basic_string_char *this, MSVCP_size_t count, char ch)
1020 {
1021     TRACE("%p %lu %c\n", this, count, ch);
1022
1023     if(MSVCP_basic_string_char_npos-this->size <= count)
1024         MSVCP__String_base_Xlen();
1025
1026     if(basic_string_char_grow(this, this->size+count, FALSE)) {
1027         MSVCP_char_traits_char_assignn(basic_string_char_ptr(this)+this->size, count, ch);
1028         basic_string_char_eos(this, this->size+count);
1029     }
1030
1031     return this;
1032 }
1033
1034 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@D@Z */
1035 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@D@Z */
1036 /* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXD@Z */
1037 /* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXD@Z */
1038 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_append_ch, 8)
1039 basic_string_char* __thiscall MSVCP_basic_string_char_append_ch(
1040         basic_string_char *this, char ch)
1041 {
1042     return MSVCP_basic_string_char_append_len_ch(this, 1, ch);
1043 }
1044
1045 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z */
1046 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@AEBV10@PEBD@Z */
1047 basic_string_char* __cdecl MSVCP_basic_string_char_concatenate_bstr_cstr(basic_string_char *ret,
1048         const basic_string_char *left, const char *right)
1049 {
1050     TRACE("%p %s\n", left, right);
1051
1052     MSVCP_basic_string_char_copy_ctor(ret, left);
1053     MSVCP_basic_string_char_append_cstr(ret, right);
1054     return ret;
1055 }
1056
1057 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PBDABV10@@Z */
1058 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PEBDAEBV10@@Z */
1059 basic_string_char* __cdecl MSVCP_basic_string_char_concatenate_cstr_bstr(basic_string_char *ret,
1060         const char *left, const basic_string_char *right)
1061 {
1062     TRACE("%s %p\n", left, right);
1063
1064     MSVCP_basic_string_char_ctor_cstr(ret, left);
1065     MSVCP_basic_string_char_append(ret, right);
1066     return ret;
1067 }
1068
1069 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z */
1070 /* ??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@AEBV10@0@Z */
1071 basic_string_char* __cdecl MSVCP_basic_string_char_concatenate(basic_string_char *ret,
1072         const basic_string_char *left, const basic_string_char *right)
1073 {
1074     TRACE("%p %p\n", left, right);
1075
1076     MSVCP_basic_string_char_copy_ctor(ret, left);
1077     MSVCP_basic_string_char_append(ret, right);
1078     return ret;
1079 }
1080
1081 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIPBDI@Z */
1082 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0PEBD0@Z */
1083 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare_substr_cstr_len, 20)
1084 int __thiscall MSVCP_basic_string_char_compare_substr_cstr_len(
1085             const basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t num,
1086             const char *str, MSVCP_size_t count)
1087 {
1088     int ans;
1089
1090     TRACE("%p %lu %lu %s %lu\n", this, pos, num, str, count);
1091
1092     if(this->size < pos)
1093         MSVCP__String_base_Xran();
1094
1095     if(pos+num > this->size)
1096         num = this->size-pos;
1097
1098     ans = MSVCP_char_traits_char_compare(basic_string_char_const_ptr(this)+pos,
1099             str, num>count ? count : num);
1100     if(ans)
1101         return ans;
1102
1103     if(num > count)
1104         ans = 1;
1105     else if(num < count)
1106         ans = -1;
1107     return ans;
1108 }
1109
1110 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIPBD@Z */
1111 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0PEBD@Z */
1112 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare_substr_cstr, 16)
1113 int __thiscall MSVCP_basic_string_char_compare_substr_cstr(const basic_string_char *this,
1114         MSVCP_size_t pos, MSVCP_size_t num, const char *str)
1115 {
1116     return MSVCP_basic_string_char_compare_substr_cstr_len(this, pos, num,
1117             str, MSVCP_char_traits_char_length(str));
1118 }
1119
1120 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHPBD@Z */
1121 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAHPEBD@Z */
1122 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare_cstr, 8)
1123 int __thiscall MSVCP_basic_string_char_compare_cstr(
1124         const basic_string_char *this, const char *str)
1125 {
1126     return MSVCP_basic_string_char_compare_substr_cstr_len(this, 0, this->size,
1127             str, MSVCP_char_traits_char_length(str));
1128 }
1129
1130 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIABV12@II@Z */
1131 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0AEBV12@00@Z */
1132 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare_substr_substr, 24)
1133 int __thiscall MSVCP_basic_string_char_compare_substr_substr(
1134         const basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t num,
1135         const basic_string_char *compare, MSVCP_size_t off, MSVCP_size_t count)
1136 {
1137     TRACE("%p %lu %lu %p %lu %lu\n", this, pos, num, compare, off, count);
1138
1139     if(compare->size < off)
1140         MSVCP__String_base_Xran();
1141
1142     if(off+count > compare->size)
1143         count = compare->size-off;
1144
1145     return MSVCP_basic_string_char_compare_substr_cstr_len(this, pos, num,
1146             basic_string_char_const_ptr(compare)+off, count);
1147 }
1148
1149 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIABV12@@Z */
1150 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0AEBV12@@Z */
1151 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare_substr, 16)
1152 int __thiscall MSVCP_basic_string_char_compare_substr(
1153         const basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t num,
1154         const basic_string_char *compare)
1155 {
1156     return MSVCP_basic_string_char_compare_substr_cstr_len(this, pos, num,
1157             basic_string_char_const_ptr(compare), compare->size);
1158 }
1159
1160 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHABV12@@Z */
1161 /* ?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAHAEBV12@@Z */
1162 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_compare, 8)
1163 int __thiscall MSVCP_basic_string_char_compare(
1164         const basic_string_char *this, const basic_string_char *compare)
1165 {
1166     return MSVCP_basic_string_char_compare_substr_cstr_len(this, 0, this->size,
1167             basic_string_char_const_ptr(compare), compare->size);
1168 }
1169
1170 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1171 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1172 MSVCP_bool __cdecl MSVCP_basic_string_char_equal(
1173         const basic_string_char *left, const basic_string_char *right)
1174 {
1175     return MSVCP_basic_string_char_compare(left, right) == 0;
1176 }
1177
1178 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PBD@Z */
1179 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PEBD@Z */
1180 MSVCP_bool __cdecl MSVCP_basic_string_char_equal_str_cstr(
1181         const basic_string_char *left, const char *right)
1182 {
1183     return MSVCP_basic_string_char_compare_cstr(left, right) == 0;
1184 }
1185
1186 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPBDABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1187 /* ??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPEBDAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1188 MSVCP_bool __cdecl MSVCP_basic_string_char_equal_cstr_str(
1189         const char *left, const basic_string_char *right)
1190 {
1191     return MSVCP_basic_string_char_compare_cstr(right, left) == 0;
1192 }
1193
1194 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1195 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1196 MSVCP_bool __cdecl MSVCP_basic_string_char_not_equal(
1197         const basic_string_char *left, const basic_string_char *right)
1198 {
1199     return MSVCP_basic_string_char_compare(left, right) != 0;
1200 }
1201
1202 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PBD@Z */
1203 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PEBD@Z */
1204 MSVCP_bool __cdecl MSVCP_basic_string_char_not_equal_str_cstr(
1205         const basic_string_char *left, const char *right)
1206 {
1207     return MSVCP_basic_string_char_compare_cstr(left, right) != 0;
1208 }
1209
1210 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPBDABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1211 /* ??$?9DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPEBDAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1212 MSVCP_bool __cdecl MSVCP_basic_string_char_not_equal_cstr_str(
1213         const char *left, const basic_string_char *right)
1214 {
1215     return MSVCP_basic_string_char_compare_cstr(right, left) != 0;
1216 }
1217
1218 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1219 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z */
1220 MSVCP_bool __cdecl MSVCP_basic_string_char_lower(
1221         const basic_string_char *left, const basic_string_char *right)
1222 {
1223     return MSVCP_basic_string_char_compare(left, right) < 0;
1224 }
1225
1226 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PBD@Z */
1227 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PEBD@Z */
1228 MSVCP_bool __cdecl MSVCP_basic_string_char_lower_bstr_cstr(
1229         const basic_string_char *left, const char *right)
1230 {
1231     return MSVCP_basic_string_char_compare_cstr(left, right) < 0;
1232 }
1233
1234 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPBDABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1235 /* ??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NPEBDAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z */
1236 MSVCP_bool __cdecl MSVCP_basic_string_char_lower_cstr_bstr(
1237         const char *left, const basic_string_char *right)
1238 {
1239     return MSVCP_basic_string_char_compare_cstr(right, left) > 0;
1240 }
1241
1242 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDII@Z */
1243 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K1@Z */
1244 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_cstr_substr, 16)
1245 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_cstr_substr(
1246         const basic_string_char *this, const char *find, MSVCP_size_t pos, MSVCP_size_t len)
1247 {
1248     const char *p, *end;
1249
1250     TRACE("%p %s %lu %lu\n", this, find, pos, len);
1251
1252     if(len==0 && pos<=this->size)
1253         return pos;
1254
1255     end = basic_string_char_const_ptr(this)+this->size-len+1;
1256     for(p=basic_string_char_const_ptr(this)+pos; p<end; p++) {
1257         p = MSVCP_char_traits_char_find(p, end-p, find);
1258         if(!p)
1259             break;
1260
1261         if(!MSVCP_char_traits_char_compare(p, find, len))
1262             return p-basic_string_char_const_ptr(this);
1263     }
1264
1265     return MSVCP_basic_string_char_npos;
1266 }
1267
1268 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDI@Z */
1269 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K@Z */
1270 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_cstr_off, 12)
1271 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_cstr_off(
1272         const basic_string_char *this, const char *find, MSVCP_size_t pos)
1273 {
1274     return MSVCP_basic_string_char_find_cstr_substr(this, find, pos,
1275             MSVCP_char_traits_char_length(find));
1276 }
1277
1278 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIABV12@I@Z */
1279 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KAEBV12@_K@Z */
1280 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_off, 12)
1281 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_off(
1282         const basic_string_char *this, const basic_string_char *find, MSVCP_size_t off)
1283 {
1284     return MSVCP_basic_string_char_find_cstr_substr(this,
1285             basic_string_char_const_ptr(find), off, find->size);
1286 }
1287
1288 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIDI@Z */
1289 /* ?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KD_K@Z */
1290 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_ch, 12)
1291 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_ch(
1292         const basic_string_char *this, char ch, MSVCP_size_t pos)
1293 {
1294     return MSVCP_basic_string_char_find_cstr_substr(this, &ch, pos, 1);
1295 }
1296
1297 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDII@Z */
1298 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K1@Z */
1299 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_first_of_cstr_substr, 16)
1300 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_first_of_cstr_substr(
1301         const basic_string_char *this, const char *find, MSVCP_size_t off, MSVCP_size_t len)
1302 {
1303     const char *p, *end;
1304
1305     TRACE("%p %p %lu %lu\n", this, find, off, len);
1306
1307     if(len>0 && off<this->size) {
1308         end = basic_string_char_const_ptr(this)+this->size;
1309         for(p=basic_string_char_const_ptr(this)+off; p<end; p++)
1310             if(MSVCP_char_traits_char_find(find, len, p))
1311                 return p-basic_string_char_const_ptr(this);
1312     }
1313
1314     return MSVCP_basic_string_char_npos;
1315 }
1316
1317 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIABV12@I@Z */
1318 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KAEBV12@_K@Z */
1319 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_first_of, 12)
1320 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_first_of(
1321         const basic_string_char *this, const basic_string_char *find, MSVCP_size_t off)
1322 {
1323     return MSVCP_basic_string_char_find_first_of_cstr_substr(this,
1324             basic_string_char_const_ptr(find), off, find->size);
1325 }
1326
1327 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDI@Z */
1328 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K@Z */
1329 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_first_of_cstr, 12)
1330 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_first_of_cstr(
1331         const basic_string_char *this, const char *find, MSVCP_size_t off)
1332 {
1333     return MSVCP_basic_string_char_find_first_of_cstr_substr(
1334             this, find, off, MSVCP_char_traits_char_length(find));
1335 }
1336
1337 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIDI@Z */
1338 /* ?find_first_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KD_K@Z */
1339 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_first_of_ch, 12)
1340 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_first_of_ch(
1341         const basic_string_char *this, char ch, MSVCP_size_t off)
1342 {
1343     return MSVCP_basic_string_char_find_first_of_cstr_substr(this, &ch, off, 1);
1344 }
1345
1346 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDII@Z */
1347 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K1@Z */
1348 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_last_of_cstr_substr, 16)
1349 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_last_of_cstr_substr(
1350         const basic_string_char *this, const char *find, MSVCP_size_t off, MSVCP_size_t len)
1351 {
1352     const char *p, *beg;
1353
1354     TRACE("%p %p %lu %lu\n", this, find, off, len);
1355
1356
1357     if(len>0 && this->size>0) {
1358         if(off >= this->size)
1359             off = this->size-1;
1360
1361         beg = basic_string_char_const_ptr(this);
1362         for(p=beg+off; p>=beg; p--)
1363             if(MSVCP_char_traits_char_find(find, len, p))
1364                 return p-beg;
1365     }
1366
1367     return MSVCP_basic_string_char_npos;
1368 }
1369
1370 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIABV12@I@Z */
1371 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KAEBV12@_K@Z */
1372 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_last_of, 12)
1373 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_last_of(
1374         const basic_string_char *this, const basic_string_char *find, MSVCP_size_t off)
1375 {
1376     return MSVCP_basic_string_char_find_last_of_cstr_substr(this,
1377             basic_string_char_const_ptr(find), off, find->size);
1378 }
1379
1380 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDI@Z */
1381 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K@Z */
1382 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_last_of_cstr, 12)
1383 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_last_of_cstr(
1384         const basic_string_char *this, const char *find, MSVCP_size_t off)
1385 {
1386     return MSVCP_basic_string_char_find_last_of_cstr_substr(
1387             this, find, off, MSVCP_char_traits_char_length(find));
1388 }
1389
1390 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIDI@Z */
1391 /* ?find_last_of@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KD_K@Z */
1392 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_find_last_of_ch, 12)
1393 MSVCP_size_t __thiscall MSVCP_basic_string_char_find_last_of_ch(
1394         const basic_string_char *this, char ch, MSVCP_size_t off)
1395 {
1396     return MSVCP_basic_string_char_find_last_of_cstr_substr(this, &ch, off, 1);
1397 }
1398
1399 /* ?at@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAADI@Z */
1400 /* ?at@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAD_K@Z */
1401 /* ??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAADI@Z */
1402 /* ??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAD_K@Z */
1403 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_at, 8)
1404 char* __thiscall MSVCP_basic_string_char_at(
1405         basic_string_char *this, MSVCP_size_t pos)
1406 {
1407     TRACE("%p %lu\n", this, pos);
1408
1409     if(this->size <= pos)
1410         MSVCP__String_base_Xran();
1411
1412     return basic_string_char_ptr(this)+pos;
1413 }
1414
1415 /* ?at@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEABDI@Z */
1416 /* ?at@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAAEBD_K@Z */
1417 /* ??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEABDI@Z */
1418 /* ??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAAEBD_K@Z */
1419 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_const_at, 8)
1420 const char* __thiscall MSVCP_basic_string_char_const_at(
1421         const basic_string_char *this, MSVCP_size_t pos)
1422 {
1423     TRACE("%p %lu\n", this, pos);
1424
1425     if(this->size <= pos)
1426         MSVCP__String_base_Xran();
1427
1428     return basic_string_char_const_ptr(this)+pos;
1429 }
1430
1431 /* ?resize@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXID@Z */
1432 /* ?resize@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAX_KD@Z */
1433 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_resize_ch, 12)
1434 void __thiscall MSVCP_basic_string_char_resize_ch(
1435         basic_string_char *this, MSVCP_size_t size, char ch)
1436 {
1437     TRACE("%p %lu %c\n", this, size, ch);
1438
1439     if(size <= this->size)
1440         MSVCP_basic_string_char_erase(this, size, this->size);
1441     else
1442         MSVCP_basic_string_char_append_len_ch(this, size-this->size, ch);
1443 }
1444
1445 /* ?resize@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXI@Z */
1446 /* ?resize@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAX_K@Z */
1447 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_resize, 8)
1448 void __thiscall MSVCP_basic_string_char_resize(
1449         basic_string_char *this, MSVCP_size_t size)
1450 {
1451     MSVCP_basic_string_char_resize_ch(this, size, '\0');
1452 }
1453
1454 /* ?clear@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ */
1455 /* ?clear@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXXZ */
1456 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_clear, 4)
1457 void __thiscall MSVCP_basic_string_char_clear(basic_string_char *this)
1458 {
1459     basic_string_char_eos(this, 0);
1460 }
1461
1462 /* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1463 /* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1464 /* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1465 /* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1466 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_char_begin, 4)
1467 String_iterator_char __thiscall MSVCP_basic_string_char_begin(basic_string_char *this)
1468 {
1469     String_iterator_char ret;
1470
1471     TRACE("%p\n", this);
1472
1473     ret.bstr = this;
1474     ret.pos = basic_string_char_const_ptr(this);
1475     return ret;
1476 }
1477
1478 /* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1479 /* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1480 /* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1481 /* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */
1482 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_char_end, 4)
1483 String_iterator_char __thiscall MSVCP_basic_string_char_end(basic_string_char *this)
1484 {
1485     String_iterator_char ret;
1486
1487     TRACE("%p\n", this);
1488
1489     ret.bstr = this;
1490     ret.pos = basic_string_char_const_ptr(this)+this->size;
1491     return ret;
1492 }
1493
1494 /* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$reverse_iterator@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1495 /* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA?AV?$reverse_iterator@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1496 /* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$reverse_iterator@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1497 /* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV?$reverse_iterator@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1498 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_char_rbegin, 4)
1499 String_reverse_iterator_char __thiscall MSVCP_basic_string_char_rbegin(basic_string_char *this)
1500 {
1501     String_reverse_iterator_char ret;
1502
1503     TRACE("%p\n", this);
1504
1505     ret.bstr = this;
1506     ret.pos = basic_string_char_const_ptr(this)+this->size;
1507     return ret;
1508 }
1509
1510 /* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$reverse_iterator@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1511 /* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA?AV?$reverse_iterator@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1512 /* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$reverse_iterator@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1513 /* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA?AV?$reverse_iterator@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
1514 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_char_rend, 4)
1515 String_reverse_iterator_char __thiscall MSVCP_basic_string_char_rend(basic_string_char *this)
1516 {
1517     String_reverse_iterator_char ret;
1518
1519     TRACE("%p\n", this);
1520
1521     ret.bstr = this;
1522     ret.pos = basic_string_char_const_ptr(this);
1523     return ret;
1524 }
1525
1526 /* ?_Pdif@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@KAIV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z */
1527 /* ?_Pdif@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@KA_KV?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z */
1528 MSVCP_size_t __cdecl MSVCP_basic_string_char_Pdif(String_iterator_char i1, String_iterator_char i2)
1529 {
1530     TRACE("(%p %p) (%p %p)\n", i1.bstr, i1.pos, i2.bstr, i2.pos);
1531
1532     if((!i1.bstr && i1.pos) || i1.bstr!=i2.bstr) {
1533         _invalid_parameter(NULL, NULL, NULL, 0, 0);
1534         return 0;
1535     }
1536
1537     return !i1.pos ? 0 : i1.pos-i2.pos;
1538 }
1539
1540 /* basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> */
1541 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2IB */
1542 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2_KB */
1543 const MSVCP_size_t MSVCP_basic_string_wchar_npos = -1;
1544
1545 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEPA_WXZ */
1546 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAPEA_WXZ */
1547 DEFINE_THISCALL_WRAPPER(basic_string_wchar_ptr, 4)
1548 wchar_t* __thiscall basic_string_wchar_ptr(basic_string_wchar *this)
1549 {
1550     if(this->res == BUF_SIZE_WCHAR-1)
1551         return this->data.buf;
1552     return this->data.ptr;
1553 }
1554
1555 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IBEPB_WXZ */
1556 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEBAPEB_WXZ */
1557 DEFINE_THISCALL_WRAPPER(basic_string_wchar_const_ptr, 4)
1558 const wchar_t* __thiscall basic_string_wchar_const_ptr(const basic_string_wchar *this)
1559 {
1560     if(this->res == BUF_SIZE_WCHAR-1)
1561         return this->data.buf;
1562     return this->data.ptr;
1563 }
1564
1565 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEXI@Z */
1566 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_K@Z */
1567 DEFINE_THISCALL_WRAPPER(basic_string_wchar_eos, 8)
1568 void __thiscall basic_string_wchar_eos(basic_string_wchar *this, MSVCP_size_t len)
1569 {
1570     static const wchar_t nullbyte_w = '\0';
1571
1572     this->size = len;
1573     MSVCP_char_traits_wchar_assign(basic_string_wchar_ptr(this)+len, &nullbyte_w);
1574 }
1575
1576 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NPB_W@Z */
1577 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_NPEB_W@Z */
1578 DEFINE_THISCALL_WRAPPER(basic_string_wchar_inside, 8)
1579 MSVCP_bool __thiscall basic_string_wchar_inside(
1580         basic_string_wchar *this, const wchar_t *ptr)
1581 {
1582     wchar_t *cstr = basic_string_wchar_ptr(this);
1583
1584     return (ptr<cstr || ptr>=cstr+this->size) ? FALSE : TRUE;
1585 }
1586
1587 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEX_NI@Z */
1588 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_N_K@Z */
1589 DEFINE_THISCALL_WRAPPER(basic_string_wchar_tidy, 12)
1590 void __thiscall basic_string_wchar_tidy(basic_string_wchar *this,
1591         MSVCP_bool built, MSVCP_size_t new_size)
1592 {
1593     if(built && BUF_SIZE_WCHAR<=this->res) {
1594         wchar_t *ptr = this->data.ptr;
1595
1596         if(new_size > 0)
1597             MSVCP_char_traits_wchar__Copy_s(this->data.buf, BUF_SIZE_WCHAR, ptr, new_size);
1598         MSVCP_allocator_wchar_deallocate(this->allocator, ptr, this->res+1);
1599     }
1600
1601     this->res = BUF_SIZE_WCHAR-1;
1602     basic_string_wchar_eos(this, new_size);
1603 }
1604
1605 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NI_N@Z */
1606 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_N_K_N@Z */
1607 DEFINE_THISCALL_WRAPPER(basic_string_wchar_grow, 12)
1608 MSVCP_bool __thiscall basic_string_wchar_grow(
1609         basic_string_wchar *this, MSVCP_size_t new_size, MSVCP_bool trim)
1610 {
1611     if(this->res < new_size) {
1612         MSVCP_size_t new_res = new_size, len = this->size;
1613         wchar_t *ptr;
1614
1615         new_res |= 0xf;
1616
1617         if(new_res/3 < this->res/2)
1618             new_res = this->res + this->res/2;
1619
1620         ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_res);
1621         if(!ptr)
1622             ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_size+1);
1623         else
1624             new_size = new_res;
1625         if(!ptr) {
1626             ERR("Out of memory\n");
1627             basic_string_wchar_tidy(this, TRUE, 0);
1628             return FALSE;
1629         }
1630
1631         MSVCP_char_traits_wchar__Copy_s(ptr, new_size,
1632                 basic_string_wchar_ptr(this), this->size);
1633         basic_string_wchar_tidy(this, TRUE, 0);
1634         this->data.ptr = ptr;
1635         this->res = new_size;
1636         basic_string_wchar_eos(this, len);
1637     } else if(trim && new_size < BUF_SIZE_WCHAR)
1638         basic_string_wchar_tidy(this, TRUE,
1639                 new_size<this->size ? new_size : this->size);
1640     else if(new_size == 0)
1641         basic_string_wchar_eos(this, 0);
1642
1643     return (new_size>0);
1644 }
1645
1646 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@II@Z */
1647 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K0@Z */
1648 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_erase, 12)
1649 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_erase(
1650             basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t len)
1651 {
1652     TRACE("%p %lu %lu\n", this, pos, len);
1653
1654     if(pos > this->size) {
1655         MSVCP__String_base_Xran();
1656         return NULL;
1657     }
1658
1659     if(len > this->size-pos)
1660         len = this->size-pos;
1661
1662     if(len) {
1663         MSVCP_char_traits_wchar__Move_s(basic_string_wchar_ptr(this)+pos,
1664                 this->res-pos, basic_string_wchar_ptr(this)+pos+len,
1665                 this->size-pos-len);
1666         basic_string_wchar_eos(this, this->size-len);
1667     }
1668
1669     return this;
1670 }
1671
1672 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@II@Z */
1673 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
1674 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_assign_substr, 16)
1675 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_assign_substr(
1676             basic_string_wchar *this, const basic_string_wchar *assign,
1677             MSVCP_size_t pos, MSVCP_size_t len)
1678 {
1679     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
1680
1681     if(assign->size < pos) {
1682         MSVCP__String_base_Xran();
1683         return NULL;
1684     }
1685
1686     if(len > assign->size-pos)
1687         len = assign->size-pos;
1688
1689     if(this == assign) {
1690         MSVCP_basic_string_wchar_erase(this, pos+len, MSVCP_basic_string_wchar_npos);
1691         MSVCP_basic_string_wchar_erase(this, 0, pos);
1692     } else if(basic_string_wchar_grow(this, len, FALSE)) {
1693         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
1694                 this->res, basic_string_wchar_const_ptr(assign)+pos, len);
1695         basic_string_wchar_eos(this, len);
1696     }
1697
1698     return this;
1699 }
1700
1701 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@@Z */
1702 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@@Z */
1703 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@ABV01@@Z */
1704 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@AEBV01@@Z */
1705 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_assign, 8)
1706 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_assign(
1707             basic_string_wchar *this, const basic_string_wchar *assign)
1708 {
1709     return MSVCP_basic_string_wchar_assign_substr(this, assign,
1710             0, MSVCP_basic_string_wchar_npos);
1711 }
1712
1713 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z */
1714 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z */
1715 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_assign_cstr_len, 12)
1716 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_assign_cstr_len(
1717             basic_string_wchar *this, const wchar_t *str, MSVCP_size_t len)
1718 {
1719     TRACE("%p %s %lu\n", this, debugstr_w(str), len);
1720
1721     if(basic_string_wchar_inside(this, str))
1722         return MSVCP_basic_string_wchar_assign_substr(this, this,
1723                 str-basic_string_wchar_ptr(this), len);
1724     else if(basic_string_wchar_grow(this, len, FALSE)) {
1725         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
1726                 this->res, str, len);
1727         basic_string_wchar_eos(this, len);
1728     }
1729
1730     return this;
1731 }
1732
1733 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@_W@Z */
1734 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@_W@Z */
1735 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_assign_ch, 8)
1736 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_assign_ch(
1737         basic_string_wchar *this, wchar_t ch)
1738 {
1739         return MSVCP_basic_string_wchar_assign_cstr_len(this, &ch, 1);
1740 }
1741
1742 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_W@Z */
1743 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W@Z */
1744 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@PB_W@Z */
1745 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@PEB_W@Z */
1746 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_assign_cstr, 8)
1747 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_assign_cstr(
1748             basic_string_wchar *this, const wchar_t *str)
1749 {
1750     return MSVCP_basic_string_wchar_assign_cstr_len(this, str,
1751             MSVCP_char_traits_wchar_length(str));
1752 }
1753
1754 /* ?_Chassign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEXII_W@Z */
1755 /* ?_Chassign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_K0_W@Z */
1756 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_Chassign, 16)
1757 void __thiscall MSVCP_basic_string_wchar_Chassign(basic_string_wchar *this,
1758         MSVCP_size_t off, MSVCP_size_t count, wchar_t ch)
1759 {
1760     TRACE("%p %lu %lu %c\n", this, off, count, ch);
1761     MSVCP_char_traits_wchar_assignn(basic_string_wchar_ptr(this)+off, count, ch);
1762 }
1763
1764 /* ?_Copy_s@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPA_WIII@Z */
1765 /* ?_Copy_s@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEA_W_K11@Z */
1766 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_Copy_s, 20)
1767 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_Copy_s(const basic_string_wchar *this,
1768         wchar_t *dest, MSVCP_size_t size, MSVCP_size_t off, MSVCP_size_t count)
1769 {
1770     TRACE("%p %p %lu %lu %lu\n", this, dest, size, off, count);
1771
1772     if(this->size < off)
1773         MSVCP__String_base_Xran();
1774
1775     if(count > this->size-off)
1776         count = this->size-off;
1777
1778     MSVCP_char_traits_wchar__Copy_s(dest, size,
1779             basic_string_wchar_const_ptr(this)+off, count);
1780     return count;
1781 }
1782
1783 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
1784 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
1785 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
1786 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
1787 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_c_str, 4)
1788 const wchar_t* __thiscall MSVCP_basic_string_wchar_c_str(basic_string_wchar *this)
1789 {
1790     TRACE("%p\n", this);
1791     return basic_string_wchar_const_ptr(this);
1792 }
1793
1794 /* ?capacity@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
1795 /* ?capacity@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
1796 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_capacity, 4)
1797 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_capacity(basic_string_wchar *this)
1798 {
1799     TRACE("%p\n", this);
1800     return this->res;
1801 }
1802
1803 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ */
1804 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ */
1805 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_ctor, 4)
1806 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_ctor(basic_string_wchar *this)
1807 {
1808     TRACE("%p\n", this);
1809
1810     basic_string_wchar_tidy(this, FALSE, 0);
1811     return this;
1812 }
1813
1814 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@ABV01@@Z */
1815 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@AEBV01@@Z */
1816 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_copy_ctor, 8)
1817 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_copy_ctor(
1818             basic_string_wchar *this, const basic_string_wchar *copy)
1819 {
1820     TRACE("%p %p\n", this, copy);
1821
1822     basic_string_wchar_tidy(this, FALSE, 0);
1823     MSVCP_basic_string_wchar_assign(this, copy);
1824     return this;
1825 }
1826
1827 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_W@Z */
1828 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z */
1829 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_ctor_cstr, 8)
1830 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_ctor_cstr(
1831             basic_string_wchar *this, const wchar_t *str)
1832 {
1833     TRACE("%p %s\n", this, debugstr_w(str));
1834
1835     basic_string_wchar_tidy(this, FALSE, 0);
1836     MSVCP_basic_string_wchar_assign_cstr(this, str);
1837     return this;
1838 }
1839
1840 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_WI@Z */
1841 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W_K@Z */
1842 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_ctor_cstr_len, 12)
1843 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_ctor_cstr_len(
1844         basic_string_wchar *this, const wchar_t *str, MSVCP_size_t len)
1845 {
1846     TRACE("%p %s %ld\n", this, debugstr_w(str), len);
1847
1848     basic_string_wchar_tidy(this, FALSE, 0);
1849     MSVCP_basic_string_wchar_assign_cstr_len(this, str, len);
1850     return this;
1851 }
1852
1853 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@ABV01@II@Z */
1854 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@AEBV01@_K1@Z */
1855 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_ctor_substr, 16)
1856 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_ctor_substr(
1857         basic_string_wchar *this, const basic_string_wchar *assign,
1858         MSVCP_size_t pos, MSVCP_size_t len)
1859 {
1860     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
1861
1862     basic_string_wchar_tidy(this, FALSE, 0);
1863     MSVCP_basic_string_wchar_assign_substr(this, assign, pos, len);
1864     return this;
1865 }
1866
1867 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@ABV?$allocator@_W@1@@Z */
1868 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@AEBV?$allocator@_W@1@@Z */
1869 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_ctor_alloc, 8)
1870     basic_string_wchar* __thiscall MSVCP_basic_string_wchar_ctor_alloc(
1871             basic_string_wchar *this, const void *alloc)
1872 {
1873     TRACE("%p %p\n", this, alloc);
1874
1875     basic_string_wchar_tidy(this, FALSE, 0);
1876     return this;
1877 }
1878
1879 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ */
1880 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ */
1881 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_dtor, 4)
1882 void __thiscall MSVCP_basic_string_wchar_dtor(basic_string_wchar *this)
1883 {
1884     TRACE("%p\n", this);
1885     basic_string_wchar_tidy(this, TRUE, 0);
1886 }
1887
1888 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
1889 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
1890 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
1891 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
1892 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_length, 4)
1893 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_length(basic_string_wchar *this)
1894 {
1895     TRACE("%p\n", this);
1896     return this->size;
1897 }
1898
1899 /* ?empty@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE_NXZ */
1900 /* ?empty@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_NXZ */
1901 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_empty, 4)
1902 MSVCP_bool __thiscall MSVCP_basic_string_wchar_empty(basic_string_wchar *this)
1903 {
1904     TRACE("%p\n", this);
1905     return this->size == 0;
1906 }
1907
1908 /* ?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXAAV12@@Z */
1909 /* ?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAXAEAV12@@Z */
1910 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_swap, 8)
1911 void __thiscall MSVCP_basic_string_wchar_swap(basic_string_wchar *this, basic_string_wchar *str)
1912 {
1913     if(this != str) {
1914         char tmp[sizeof(this->data)];
1915         const MSVCP_size_t size = this->size;
1916         const MSVCP_size_t res = this->res;
1917
1918         memcpy(tmp, this->data.buf, sizeof(this->data));
1919         memcpy(this->data.buf, str->data.buf, sizeof(this->data));
1920         memcpy(str->data.buf, tmp, sizeof(this->data));
1921
1922         this->size = str->size;
1923         this->res = str->res;
1924
1925         str->size = size;
1926         str->res = res;
1927     }
1928 }
1929
1930 /* ?substr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV12@II@Z */
1931 /* ?substr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA?AV12@_K0@Z */
1932 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_wchar_substr, 12)
1933 basic_string_wchar __thiscall MSVCP_basic_string_wchar_substr(
1934         basic_string_wchar *this, MSVCP_size_t off, MSVCP_size_t len)
1935 {
1936     basic_string_wchar ret = { 0 };
1937     TRACE("%p %lu %lu\n", this, off, len);
1938
1939     MSVCP_basic_string_wchar_ctor_substr(&ret, this, off, len);
1940     return ret;
1941 }
1942
1943 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@II@Z */
1944 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
1945 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_substr, 16)
1946 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_substr(basic_string_wchar *this,
1947         const basic_string_wchar *append, MSVCP_size_t offset, MSVCP_size_t count)
1948 {
1949     TRACE("%p %p %lu %lu\n", this, append, offset, count);
1950
1951     if(append->size < offset)
1952         MSVCP__String_base_Xran();
1953
1954     if(count > append->size-offset)
1955         count = append->size-offset;
1956
1957     if(MSVCP_basic_string_wchar_npos-this->size<=count || this->size+count<this->size)
1958         MSVCP__String_base_Xlen();
1959
1960     if(basic_string_wchar_grow(this, this->size+count, FALSE)) {
1961         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this)+this->size,
1962                 this->res-this->size, basic_string_wchar_const_ptr(append)+offset, count);
1963         basic_string_wchar_eos(this, this->size+count);
1964     }
1965
1966     return this;
1967 }
1968
1969 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@@Z */
1970 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@@Z */
1971 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@ABV01@@Z */
1972 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@AEBV01@@Z */
1973 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append, 8)
1974 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append(
1975             basic_string_wchar *this, const basic_string_wchar *append)
1976 {
1977     return MSVCP_basic_string_wchar_append_substr(this, append,
1978             0, MSVCP_basic_string_wchar_npos);
1979 }
1980
1981 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z */
1982 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z */
1983 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_cstr_len, 12)
1984 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_cstr_len(
1985         basic_string_wchar *this, const wchar_t *append, MSVCP_size_t count)
1986 {
1987     TRACE("%p %s %lu\n", this, debugstr_w(append), count);
1988
1989     if(basic_string_wchar_inside(this, append))
1990         return MSVCP_basic_string_wchar_append_substr(this, this,
1991                 append-basic_string_wchar_ptr(this), count);
1992
1993     if(MSVCP_basic_string_wchar_npos-this->size<=count || this->size+count<this->size)
1994         MSVCP__String_base_Xlen();
1995
1996     if(basic_string_wchar_grow(this, this->size+count, FALSE)) {
1997         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this)+this->size,
1998                 this->res-this->size, append, count);
1999         basic_string_wchar_eos(this, this->size+count);
2000     }
2001
2002     return this;
2003 }
2004
2005 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_W@Z */
2006 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W@Z */
2007 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@PB_W@Z */
2008 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@PEB_W@Z */
2009 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_cstr, 8)
2010 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_cstr(
2011         basic_string_wchar *this, const wchar_t *append)
2012 {
2013     return MSVCP_basic_string_wchar_append_cstr_len(this, append,
2014             MSVCP_char_traits_wchar_length(append));
2015 }
2016
2017 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_W0@Z */
2018 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W0@Z */
2019 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_beg_end, 12)
2020 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_beg_end(
2021         basic_string_wchar *this, const wchar_t *beg, const wchar_t *end)
2022 {
2023     return MSVCP_basic_string_wchar_append_cstr_len(this, beg, end-beg);
2024 }
2025
2026 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z */
2027 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z */
2028 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_iter, 20)
2029 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_iter(
2030         basic_string_wchar *this, String_iterator_wchar beg, String_iterator_wchar end)
2031 {
2032     return MSVCP_basic_string_wchar_append_cstr_len(this, beg.pos, end.pos-beg.pos+1);
2033 }
2034
2035 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@I_W@Z */
2036 /* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K_W@Z */
2037 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_len_ch, 12)
2038 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_len_ch(
2039         basic_string_wchar *this, MSVCP_size_t count, wchar_t ch)
2040 {
2041     TRACE("%p %lu %c\n", this, count, ch);
2042
2043     if(MSVCP_basic_string_wchar_npos-this->size <= count)
2044         MSVCP__String_base_Xlen();
2045
2046     if(basic_string_wchar_grow(this, this->size+count, FALSE)) {
2047         MSVCP_char_traits_wchar_assignn(basic_string_wchar_ptr(this)+this->size, count, ch);
2048         basic_string_wchar_eos(this, this->size+count);
2049     }
2050
2051     return this;
2052 }
2053
2054 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@_W@Z */
2055 /* ??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@_W@Z */
2056 /* ?push_back@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEX_W@Z */
2057 /* ?push_back@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAX_W@Z */
2058 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_append_ch, 8)
2059 basic_string_wchar* __thiscall MSVCP_basic_string_wchar_append_ch(
2060         basic_string_wchar *this, wchar_t ch)
2061 {
2062     return MSVCP_basic_string_wchar_append_len_ch(this, 1, ch);
2063 }
2064
2065 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@ABV10@PB_W@Z */
2066 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@AEBV10@PEB_W@Z */
2067 basic_string_wchar* __cdecl MSVCP_basic_string_wchar_concatenate_bstr_cstr(basic_string_wchar *ret,
2068         const basic_string_wchar *left, const wchar_t *right)
2069 {
2070     TRACE("%p %s\n", left, debugstr_w(right));
2071
2072     MSVCP_basic_string_wchar_copy_ctor(ret, left);
2073     MSVCP_basic_string_wchar_append_cstr(ret, right);
2074     return ret;
2075 }
2076
2077 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PB_WABV10@@Z */
2078 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PEB_WAEBV10@@Z */
2079 basic_string_wchar* __cdecl MSVCP_basic_string_wchar_concatenate_cstr_bstr(basic_string_wchar *ret,
2080         const wchar_t *left, const basic_string_wchar *right)
2081 {
2082     TRACE("%s %p\n", debugstr_w(left), right);
2083
2084     MSVCP_basic_string_wchar_ctor_cstr(ret, left);
2085     MSVCP_basic_string_wchar_append(ret, right);
2086     return ret;
2087 }
2088
2089 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@ABV10@0@Z */
2090 /* ??$?H_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@AEBV10@0@Z */
2091 basic_string_wchar* __cdecl MSVCP_basic_string_wchar_concatenate(basic_string_wchar *ret,
2092         const basic_string_wchar *left, const basic_string_wchar *right)
2093 {
2094     TRACE("%p %p\n", left, right);
2095
2096     MSVCP_basic_string_wchar_copy_ctor(ret, left);
2097     MSVCP_basic_string_wchar_append(ret, right);
2098     return ret;
2099 }
2100
2101 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHIIPB_WI@Z */
2102 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAH_K0PEB_W0@Z */
2103 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare_substr_cstr_len, 20)
2104 int __thiscall MSVCP_basic_string_wchar_compare_substr_cstr_len(
2105         const basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t num,
2106         const wchar_t *str, MSVCP_size_t count)
2107 {
2108     int ans;
2109
2110     TRACE("%p %lu %lu %s %lu\n", this, pos, num, debugstr_w(str), count);
2111
2112     if(this->size < pos)
2113         MSVCP__String_base_Xran();
2114
2115     if(pos+num > this->size)
2116         num = this->size-pos;
2117
2118     ans = MSVCP_char_traits_wchar_compare(basic_string_wchar_const_ptr(this)+pos,
2119             str, num>count ? count : num);
2120     if(ans)
2121         return ans;
2122
2123     if(num > count)
2124         ans = 1;
2125     else if(num < count)
2126         ans = -1;
2127     return ans;
2128 }
2129
2130 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHIIPB_W@Z */
2131 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAH_K0PEB_W@Z */
2132 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare_substr_cstr, 16)
2133 int __thiscall MSVCP_basic_string_wchar_compare_substr_cstr(const basic_string_wchar *this,
2134         MSVCP_size_t pos, MSVCP_size_t num, const wchar_t *str)
2135 {
2136     return MSVCP_basic_string_wchar_compare_substr_cstr_len(this, pos, num,
2137             str, MSVCP_char_traits_wchar_length(str));
2138 }
2139
2140 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHPB_W@Z */
2141 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAHPEB_W@Z */
2142 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare_cstr, 8)
2143 int __thiscall MSVCP_basic_string_wchar_compare_cstr(
2144         const basic_string_wchar *this, const wchar_t *str)
2145 {
2146     return MSVCP_basic_string_wchar_compare_substr_cstr_len(this, 0, this->size,
2147             str, MSVCP_char_traits_wchar_length(str));
2148 }
2149
2150 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHIIABV12@II@Z */
2151 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAH_K0AEBV12@00@Z */
2152 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare_substr_substr, 24)
2153 int __thiscall MSVCP_basic_string_wchar_compare_substr_substr(
2154         const basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t num,
2155         const basic_string_wchar *compare, MSVCP_size_t off, MSVCP_size_t count)
2156 {
2157     TRACE("%p %lu %lu %p %lu %lu\n", this, pos, num, compare, off, count);
2158
2159     if(compare->size < off)
2160         MSVCP__String_base_Xran();
2161
2162     if(off+count > compare->size)
2163         count = compare->size-off;
2164
2165     return MSVCP_basic_string_wchar_compare_substr_cstr_len(this, pos, num,
2166             basic_string_wchar_const_ptr(compare)+off, count);
2167 }
2168
2169 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHIIABV12@@Z */
2170 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAH_K0AEBV12@@Z */
2171 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare_substr, 16)
2172 int __thiscall MSVCP_basic_string_wchar_compare_substr(
2173         const basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t num,
2174         const basic_string_wchar *compare)
2175 {
2176     return MSVCP_basic_string_wchar_compare_substr_cstr_len(this, pos, num,
2177             basic_string_wchar_const_ptr(compare), compare->size);
2178 }
2179
2180 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEHABV12@@Z */
2181 /* ?compare@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAHAEBV12@@Z */
2182 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_compare, 8)
2183 int __thiscall MSVCP_basic_string_wchar_compare(
2184         const basic_string_wchar *this, const basic_string_wchar *compare)
2185 {
2186     return MSVCP_basic_string_wchar_compare_substr_cstr_len(this, 0, this->size,
2187             basic_string_wchar_const_ptr(compare), compare->size);
2188 }
2189
2190 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2191 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2192 MSVCP_bool __cdecl MSVCP_basic_string_wchar_equal(
2193         const basic_string_wchar *left, const basic_string_wchar *right)
2194 {
2195     return MSVCP_basic_string_wchar_compare(left, right) == 0;
2196 }
2197
2198 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PB_W@Z */
2199 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PEB_W@Z */
2200 MSVCP_bool __cdecl MSVCP_basic_string_wchar_equal_str_cstr(
2201         const basic_string_wchar *left, const wchar_t *right)
2202 {
2203     return MSVCP_basic_string_wchar_compare_cstr(left, right) == 0;
2204 }
2205
2206 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPB_WABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2207 /* ??$?8_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPEB_WAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2208 MSVCP_bool __cdecl MSVCP_basic_string_wchar_equal_cstr_str(
2209         const wchar_t *left, const basic_string_wchar *right)
2210 {
2211     return MSVCP_basic_string_wchar_compare_cstr(right, left) == 0;
2212 }
2213
2214 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2215 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2216 MSVCP_bool __cdecl MSVCP_basic_string_wchar_not_equal(
2217         const basic_string_wchar *left, const basic_string_wchar *right)
2218 {
2219     return MSVCP_basic_string_wchar_compare(left, right) != 0;
2220 }
2221
2222 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PB_W@Z */
2223 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PEB_W@Z */
2224 MSVCP_bool __cdecl MSVCP_basic_string_wchar_not_equal_str_cstr(
2225         const basic_string_wchar *left, const wchar_t *right)
2226 {
2227     return MSVCP_basic_string_wchar_compare_cstr(left, right) != 0;
2228 }
2229
2230 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPB_WABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2231 /* ??$?9_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPEB_WAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2232 MSVCP_bool __cdecl MSVCP_basic_string_wchar_not_equal_cstr_str(
2233         const wchar_t *left, const basic_string_wchar *right)
2234 {
2235     return MSVCP_basic_string_wchar_compare_cstr(right, left) != 0;
2236 }
2237
2238 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2239 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@0@Z */
2240 MSVCP_bool __cdecl MSVCP_basic_string_wchar_lower(
2241         const basic_string_wchar *left, const basic_string_wchar *right)
2242 {
2243     return MSVCP_basic_string_wchar_compare(left, right) < 0;
2244 }
2245
2246 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PB_W@Z */
2247 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@PEB_W@Z */
2248 MSVCP_bool __cdecl MSVCP_basic_string_wchar_lower_bstr_cstr(
2249         const basic_string_wchar *left, const wchar_t *right)
2250 {
2251     return MSVCP_basic_string_wchar_compare_cstr(left, right) < 0;
2252 }
2253
2254 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPB_WABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2255 /* ??$?M_WU?$char_traits@_W@std@@V?$allocator@_W@1@@std@@YA_NPEB_WAEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@@Z */
2256 MSVCP_bool __cdecl MSVCP_basic_string_wchar_lower_cstr_bstr(
2257         const wchar_t *left, const basic_string_wchar *right)
2258 {
2259     return MSVCP_basic_string_wchar_compare_cstr(right, left) > 0;
2260 }
2261
2262 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WII@Z */
2263 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K1@Z */
2264 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_cstr_substr, 16)
2265 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_cstr_substr(
2266         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t pos, MSVCP_size_t len)
2267 {
2268     const wchar_t *p, *end;
2269
2270     TRACE("%p %s %lu %lu\n", this, debugstr_w(find), pos, len);
2271
2272     if(len==0 && pos<=this->size)
2273         return pos;
2274
2275     end = basic_string_wchar_const_ptr(this)+this->size-len+1;
2276     for(p=basic_string_wchar_const_ptr(this)+pos; p<end; p++) {
2277         p = MSVCP_char_traits_wchar_find(p, end-p, find);
2278         if(!p)
2279             break;
2280
2281         if(!MSVCP_char_traits_wchar_compare(p, find, len))
2282             return p-basic_string_wchar_const_ptr(this);
2283     }
2284
2285     return MSVCP_basic_string_wchar_npos;
2286 }
2287
2288 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WI@Z */
2289 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K@Z */
2290 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_cstr_off, 12)
2291 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_cstr_off(
2292         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t pos)
2293 {
2294     return MSVCP_basic_string_wchar_find_cstr_substr(this, find, pos,
2295             MSVCP_char_traits_wchar_length(find));
2296 }
2297
2298 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIABV12@I@Z */
2299 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KAEBV12@_K@Z */
2300 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_off, 12)
2301 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_off(
2302         const basic_string_wchar *this, const basic_string_wchar *find, MSVCP_size_t off)
2303 {
2304     return MSVCP_basic_string_wchar_find_cstr_substr(this,
2305             basic_string_wchar_const_ptr(find), off, find->size);
2306 }
2307
2308 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEI_WI@Z */
2309 /* ?find@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_K_W_K@Z */
2310 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_ch, 12)
2311 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_ch(
2312         const basic_string_wchar *this, wchar_t ch, MSVCP_size_t pos)
2313 {
2314     return MSVCP_basic_string_wchar_find_cstr_substr(this, &ch, pos, 1);
2315 }
2316
2317 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WII@Z */
2318 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K1@Z */
2319 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_first_of_cstr_substr, 16)
2320 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_first_of_cstr_substr(
2321         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t off, MSVCP_size_t len)
2322 {
2323     const wchar_t *p, *end;
2324
2325     TRACE("%p %p %lu %lu\n", this, find, off, len);
2326
2327     if(len>0 && off<this->size) {
2328         end = basic_string_wchar_const_ptr(this)+this->size;
2329         for(p=basic_string_wchar_const_ptr(this)+off; p<end; p++)
2330             if(MSVCP_char_traits_wchar_find(find, len, p))
2331                 return p-basic_string_wchar_const_ptr(this);
2332     }
2333
2334     return MSVCP_basic_string_wchar_npos;
2335 }
2336
2337 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIABV12@I@Z */
2338 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KAEBV12@_K@Z */
2339 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_first_of, 12)
2340 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_first_of(
2341         const basic_string_wchar *this, const basic_string_wchar *find, MSVCP_size_t off)
2342 {
2343     return MSVCP_basic_string_wchar_find_first_of_cstr_substr(this,
2344             basic_string_wchar_const_ptr(find), off, find->size);
2345 }
2346
2347 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WI@Z */
2348 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K@Z */
2349 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_first_of_cstr, 12)
2350 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_first_of_cstr(
2351         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t off)
2352 {
2353     return MSVCP_basic_string_wchar_find_first_of_cstr_substr(
2354             this, find, off, MSVCP_char_traits_wchar_length(find));
2355 }
2356
2357 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEI_WI@Z */
2358 /* ?find_first_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_K_W_K@Z */
2359 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_first_of_ch, 12)
2360 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_first_of_ch(
2361         const basic_string_wchar *this, wchar_t ch, MSVCP_size_t off)
2362 {
2363     return MSVCP_basic_string_wchar_find_first_of_cstr_substr(this, &ch, off, 1);
2364 }
2365
2366 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WII@Z */
2367 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K1@Z */
2368 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_last_of_cstr_substr, 16)
2369 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_last_of_cstr_substr(
2370         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t off, MSVCP_size_t len)
2371 {
2372     const wchar_t *p, *beg;
2373
2374     TRACE("%p %p %lu %lu\n", this, find, off, len);
2375
2376
2377     if(len>0 && this->size>0) {
2378         if(off >= this->size)
2379             off = this->size-1;
2380
2381         beg = basic_string_wchar_const_ptr(this);
2382         for(p=beg+off; p>=beg; p--)
2383             if(MSVCP_char_traits_wchar_find(find, len, p))
2384                 return p-beg;
2385     }
2386
2387     return MSVCP_basic_string_wchar_npos;
2388 }
2389
2390 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIABV12@I@Z */
2391 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KAEBV12@_K@Z */
2392 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_last_of, 12)
2393 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_last_of(
2394         const basic_string_wchar *this, const basic_string_wchar *find, MSVCP_size_t off)
2395 {
2396     return MSVCP_basic_string_wchar_find_last_of_cstr_substr(this,
2397             basic_string_wchar_const_ptr(find), off, find->size);
2398 }
2399
2400 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIPB_WI@Z */
2401 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KPEB_W_K@Z */
2402 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_last_of_cstr, 12)
2403 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_last_of_cstr(
2404         const basic_string_wchar *this, const wchar_t *find, MSVCP_size_t off)
2405 {
2406     return MSVCP_basic_string_wchar_find_last_of_cstr_substr(
2407             this, find, off, MSVCP_char_traits_wchar_length(find));
2408 }
2409
2410 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEI_WI@Z */
2411 /* ?find_last_of@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_K_W_K@Z */
2412 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_find_last_of_ch, 12)
2413 MSVCP_size_t __thiscall MSVCP_basic_string_wchar_find_last_of_ch(
2414         const basic_string_wchar *this, wchar_t ch, MSVCP_size_t off)
2415 {
2416     return MSVCP_basic_string_wchar_find_last_of_cstr_substr(this, &ch, off, 1);
2417 }
2418
2419 /* ?at@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAA_WI@Z */
2420 /* ?at@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEA_W_K@Z */
2421 /* ??A?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAA_WI@Z */
2422 /* ??A?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEA_W_K@Z */
2423 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_at, 8)
2424 wchar_t* __thiscall MSVCP_basic_string_wchar_at(
2425         basic_string_wchar *this, MSVCP_size_t pos)
2426 {
2427     TRACE("%p %lu\n", this, pos);
2428
2429     if(this->size <= pos)
2430         MSVCP__String_base_Xran();
2431
2432     return basic_string_wchar_ptr(this)+pos;
2433 }
2434
2435 /* ?at@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEAB_WI@Z */
2436 /* ?at@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAAEB_W_K@Z */
2437 /* ??A?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEAB_WI@Z */
2438 /* ??A?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAAEB_W_K@Z */
2439 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_const_at, 8)
2440 const wchar_t* __thiscall MSVCP_basic_string_wchar_const_at(
2441         const basic_string_wchar *this, MSVCP_size_t pos)
2442 {
2443     TRACE("%p %lu\n", this, pos);
2444
2445     if(this->size <= pos)
2446         MSVCP__String_base_Xran();
2447
2448     return basic_string_wchar_const_ptr(this)+pos;
2449 }
2450
2451 /* ?resize@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXI_W@Z */
2452 /* ?resize@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAX_K_W@Z */
2453 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_resize_ch, 12)
2454 void __thiscall MSVCP_basic_string_wchar_resize_ch(
2455         basic_string_wchar *this, MSVCP_size_t size, wchar_t ch)
2456 {
2457     TRACE("%p %lu %c\n", this, size, ch);
2458
2459     if(size <= this->size)
2460         MSVCP_basic_string_wchar_erase(this, size, this->size);
2461     else
2462         MSVCP_basic_string_wchar_append_len_ch(this, size-this->size, ch);
2463 }
2464
2465 /* ?resize@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXI@Z */
2466 /* ?resize@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAX_K@Z */
2467 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_resize, 8)
2468 void __thiscall MSVCP_basic_string_wchar_resize(
2469         basic_string_wchar *this, MSVCP_size_t size)
2470 {
2471     MSVCP_basic_string_wchar_resize_ch(this, size, '\0');
2472 }
2473
2474 /* ?clear@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXXZ */
2475 /* ?clear@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAXXZ */
2476 DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_wchar_clear, 4)
2477 void __thiscall MSVCP_basic_string_wchar_clear(basic_string_wchar *this)
2478 {
2479     basic_string_wchar_eos(this, 0);
2480 }
2481
2482 /* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2483 /* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA?AV?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2484 /* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2485 /* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA?AV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2486 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_wchar_begin, 4)
2487 String_iterator_wchar __thiscall MSVCP_basic_string_wchar_begin(basic_string_wchar *this)
2488 {
2489     String_iterator_wchar ret;
2490
2491     TRACE("%p\n", this);
2492
2493     ret.bstr = this;
2494     ret.pos = basic_string_wchar_const_ptr(this);
2495     return ret;
2496 }
2497
2498 /* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2499 /* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA?AV?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2500 /* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2501 /* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA?AV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */
2502 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_wchar_end, 4)
2503 String_iterator_wchar __thiscall MSVCP_basic_string_wchar_end(basic_string_wchar *this)
2504 {
2505     String_iterator_wchar ret;
2506
2507     TRACE("%p\n", this);
2508
2509     ret.bstr = this;
2510     ret.pos = basic_string_wchar_const_ptr(this)+this->size;
2511     return ret;
2512 }
2513
2514 /* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$reverse_iterator@V?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2515 /* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA?AV?$reverse_iterator@V?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2516 /* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$reverse_iterator@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2517 /* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA?AV?$reverse_iterator@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2518 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_wchar_rbegin, 4)
2519 String_reverse_iterator_wchar __thiscall MSVCP_basic_string_wchar_rbegin(basic_string_wchar *this)
2520 {
2521     String_reverse_iterator_wchar ret;
2522
2523     TRACE("%p\n", this);
2524
2525     ret.bstr = this;
2526     ret.pos = basic_string_wchar_const_ptr(this)+this->size;
2527     return ret;
2528 }
2529
2530 /* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$reverse_iterator@V?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2531 /* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA?AV?$reverse_iterator@V?$_String_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2532 /* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$reverse_iterator@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2533 /* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA?AV?$reverse_iterator@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
2534 DEFINE_THISCALL_WRAPPER_RETPTR(MSVCP_basic_string_wchar_rend, 4)
2535 String_reverse_iterator_wchar __thiscall MSVCP_basic_string_wchar_rend(basic_string_wchar *this)
2536 {
2537     String_reverse_iterator_wchar ret;
2538
2539     TRACE("%p\n", this);
2540
2541     ret.bstr = this;
2542     ret.pos = basic_string_wchar_const_ptr(this);
2543     return ret;
2544 }
2545
2546 /* ?_Pdif@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@KAIV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z */
2547 /* ?_Pdif@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@KA_KV?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z */
2548 MSVCP_size_t __cdecl MSVCP_basic_string_wchar_Pdif(String_iterator_wchar i1, String_iterator_wchar i2)
2549 {
2550     TRACE("(%p %p) (%p %p)\n", i1.bstr, i1.pos, i2.bstr, i2.pos);
2551
2552     if((!i1.bstr && i1.pos) || i1.bstr!=i2.bstr) {
2553         _invalid_parameter(NULL, NULL, NULL, 0, 0);
2554         return 0;
2555     }
2556
2557     return !i1.pos ? 0 : i1.pos-i2.pos;
2558 }