1 // xstring internal header (from <string>)
2 #pragma once
3 #ifndef _XSTRING_
4 #define _XSTRING_
5 #ifndef RC_INVOKED
6 #include <xmemory>
7
8 #ifdef _MSC_VER
9  #pragma pack(push,_CRT_PACKING)
10  #pragma warning(push,3)
11  #pragma warning(disable:4412)
12 #endif  /* _MSC_VER */
13
14  #define _DEFINE_DLL_OVERLOADS 0
15  #define _NO_DEBUG_PLACEHOLDER _No_debug_placeholder = _No_debug_placeholder()
16
17 _STD_BEGIN
18
19   #pragma warning(disable:4251)
20
21 template<class _Elem,
22     class _Traits = char_traits<_Elem>,
23     class _Ax = allocator<_Elem> >
24     class basic_string;
25
26         // TEMPLATE CLASS _String_const_iterator
27 template<class _Elem,
28     class _Traits,
29     class _Alloc>
30     class _String_const_iterator
31         : public _Ranit_base<_Elem, typename _Alloc::difference_type,
32             typename _Alloc::const_pointer, typename _Alloc::const_reference, _Iterator_base_secure>
33     {    // iterator for nonmutable string
34 public:
35     typedef _String_const_iterator<_Elem, _Traits, _Alloc> _Myt;
36     typedef basic_string<_Elem, _Traits, _Alloc> _Mystring;
37
38     typedef random_access_iterator_tag iterator_category;
39     typedef _Elem value_type;
40     typedef typename _Alloc::difference_type difference_type;
41     typedef typename _Alloc::const_pointer pointer;
42     typedef typename _Alloc::const_reference reference;
43     typedef _Elem* _Inner_type;
44
45 #if _SECURE_SCL
46     typedef _Range_checked_iterator_tag _Checked_iterator_category;
47 #endif
48
49 #if _SECURE_SCL && !_HAS_ITERATOR_DEBUGGING
50     typedef pointer _Checked_iterator_base_type;
51
52     _Checked_iterator_base_type _Checked_iterator_base() const
53     {
54         return _Myptr;
55     }
56
57     void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
58     {
59         this->_Myptr = _Base;
60     }
61 #endif
62
63     __CLR_OR_THIS_CALL _String_const_iterator()
64         {    // construct with null pointer
65         _Myptr = 0;
66         }
67
68  #if _HAS_ITERATOR_DEBUGGING
69  #define _STRING_CONST_ITERATOR(ptr)    const_iterator(ptr, this)
70
71     __CLR_OR_THIS_CALL _String_const_iterator(pointer _Ptr, const _Container_base_secure *_Pstring)
72         {    // construct with pointer _Ptr
73         _SCL_SECURE_VALIDATE(
74             _Pstring == NULL || 
75             _Ptr != NULL && 
76             ((_Mystring *)_Pstring)->_Myptr() <= _Ptr && _Ptr <= (((_Mystring *)_Pstring)->_Myptr() + ((_Mystring *)_Pstring)->_Mysize));
77         this->_Adopt(_Pstring);
78         _Myptr = _Ptr;
79         }
80
81  #elif _SECURE_SCL
82  #define _STRING_CONST_ITERATOR(ptr)    const_iterator(ptr, this)
83         __CLR_OR_THIS_CALL _String_const_iterator(pointer _Ptr, const _Container_base_secure *_Pstring)
84             {    // construct with pointer _Ptr
85             _SCL_SECURE_VALIDATE(
86                 _Pstring != NULL && 
87                 _Ptr != NULL && 
88                 ((_Mystring *)_Pstring)->_Myptr() <= _Ptr && _Ptr <= (((_Mystring *)_Pstring)->_Myptr() + ((_Mystring *)_Pstring)->_Mysize));
89             this->_Mycont = _Pstring;
90             _Myptr = _Ptr;
91             }
92
93  #else /* _HAS_ITERATOR_DEBUGGING */
94  #define _STRING_CONST_ITERATOR(ptr)    const_iterator(ptr)
95
96     __CLR_OR_THIS_CALL _String_const_iterator(pointer _Ptr)
97         {    // construct with pointer _Ptr
98         _Myptr = _Ptr;
99         this->_Mycont = _IGNORE_MYCONT;
100         }
101  #endif /* _HAS_ITERATOR_DEBUGGING */
102
103     reference __CLR_OR_THIS_CALL operator*() const
104         {    // return designated object
105
106  #if _HAS_ITERATOR_DEBUGGING
107         if (this->_Mycont == 0 || _Myptr == 0
108             || _Myptr < ((_Mystring *)this->_Mycont)->_Myptr()
109             || ((_Mystring *)this->_Mycont)->_Myptr()
110                 + ((_Mystring *)this->_Mycont)->_Mysize <= _Myptr)
111             {
112             _DEBUG_ERROR("string iterator not dereferencable");
113             _SCL_SECURE_OUT_OF_RANGE;
114             }
115         __analysis_assume(_Myptr != 0);
116  #else
117         if (this->_Mycont != _IGNORE_MYCONT)
118         {
119             _SCL_SECURE_VALIDATE(this->_Has_container());
120             _SCL_SECURE_VALIDATE_RANGE(_Myptr < (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)(this->_Mycont))->_Mysize));
121         }
122  #endif /* _HAS_ITERATOR_DEBUGGING */
123
124         return (*_Myptr);
125         }
126
127     pointer __CLR_OR_THIS_CALL operator->() const
128         {    // return pointer to class object
129         return (&**this);
130         }
131
132     _Myt& __CLR_OR_THIS_CALL operator++()
133         {    // preincrement
134         if (this->_Mycont != _IGNORE_MYCONT)
135         {
136             _SCL_SECURE_VALIDATE(this->_Has_container());
137             _SCL_SECURE_VALIDATE_RANGE(_Myptr < (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)this->_Mycont)->_Mysize));
138         }
139         ++_Myptr;
140         return (*this);
141         }
142
143     _Myt __CLR_OR_THIS_CALL operator++(int)
144         {    // postincrement
145         _Myt _Tmp = *this;
146         ++*this;
147         return (_Tmp);
148         }
149
150     _Myt& __CLR_OR_THIS_CALL operator--()
151         {    // predecrement
152         if (this->_Mycont != _IGNORE_MYCONT)
153         {
154             _SCL_SECURE_VALIDATE(this->_Has_container());
155             _SCL_SECURE_VALIDATE_RANGE(_Myptr > ((_Mystring *)this->_Mycont)->_Myptr());
156         }
157         --_Myptr;
158         return (*this);
159         }
160
161     _Myt __CLR_OR_THIS_CALL operator--(int)
162         {    // postdecrement
163         _Myt _Tmp = *this;
164         --*this;
165         return (_Tmp);
166         }
167
168     _Myt& __CLR_OR_THIS_CALL operator+=(difference_type _Off)
169         {    // increment by integer
170         if (this->_Mycont != _IGNORE_MYCONT)
171         {
172             _SCL_SECURE_VALIDATE(this->_Has_container());
173             _SCL_SECURE_VALIDATE_RANGE(
174                 _Myptr + _Off <= (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)this->_Mycont)->_Mysize) &&
175                 _Myptr + _Off >= ((_Mystring *)this->_Mycont)->_Myptr());
176         }
177         _Myptr += _Off;
178         return (*this);
179         }
180
181     _Myt __CLR_OR_THIS_CALL operator+(difference_type _Off) const
182         {    // return this + integer
183         _Myt _Tmp = *this;
184         return (_Tmp += _Off);
185         }
186
187     _Myt& __CLR_OR_THIS_CALL operator-=(difference_type _Off)
188         {    // decrement by integer
189         return (*this += -_Off);
190         }
191
192     _Myt __CLR_OR_THIS_CALL operator-(difference_type _Off) const
193         {    // return this - integer
194         _Myt _Tmp = *this;
195         return (_Tmp -= _Off);
196         }
197
198     difference_type __CLR_OR_THIS_CALL operator-(const _Myt& _Right) const
199         {    // return difference of iterators
200
201  #if _HAS_ITERATOR_DEBUGGING
202         _Compat(_Right);
203  #else
204         if (this->_Mycont != _IGNORE_MYCONT)
205         {
206             _SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
207         }
208  #endif /* _HAS_ITERATOR_DEBUGGING */
209
210         return (_Myptr - _Right._Myptr);
211         }
212
213     reference __CLR_OR_THIS_CALL operator[](difference_type _Off) const
214         {    // subscript
215         return (*(*this + _Off));
216         }
217
218     bool __CLR_OR_THIS_CALL operator==(const _Myt& _Right) const
219         {    // test for iterator equality
220
221  #if _HAS_ITERATOR_DEBUGGING
222         _Compat(_Right);
223  #else
224         if (this->_Mycont != _IGNORE_MYCONT)
225         {
226             _SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
227         }
228  #endif /* _HAS_ITERATOR_DEBUGGING */
229
230         return (_Myptr == _Right._Myptr);
231         }
232
233     bool __CLR_OR_THIS_CALL operator!=(const _Myt& _Right) const
234         {    // test for iterator inequality
235         return (!(*this == _Right));
236         }
237
238     bool __CLR_OR_THIS_CALL operator<(const _Myt& _Right) const
239         {    // test if this < _Right
240
241  #if _HAS_ITERATOR_DEBUGGING
242         _Compat(_Right);
243  #else
244         if (this->_Mycont != _IGNORE_MYCONT)
245         {
246             _SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
247         }
248  #endif /* _HAS_ITERATOR_DEBUGGING */
249
250         return (_Myptr < _Right._Myptr);
251         }
252
253     bool __CLR_OR_THIS_CALL operator>(const _Myt& _Right) const
254         {    // test if this > _Right
255         return (_Right < *this);
256         }
257
258     bool __CLR_OR_THIS_CALL operator<=(const _Myt& _Right) const
259         {    // test if this <= _Right
260         return (!(_Right < *this));
261         }
262
263     bool __CLR_OR_THIS_CALL operator>=(const _Myt& _Right) const
264         {    // test if this >= _Right
265         return (!(*this < _Right));
266         }
267
268  #if _HAS_ITERATOR_DEBUGGING
269     void __CLR_OR_THIS_CALL _Compat(const _Myt& _Right) const
270         {    // test for compatible iterator pair
271         if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)
272             {
273             _DEBUG_ERROR("string iterators incompatible");
274             _SCL_SECURE_INVALID_ARGUMENT;
275             }
276         }
277  #endif /* _HAS_ITERATOR_DEBUGGING */
278
279     static void __cdecl _Xlen()
280         {
281         _Mystring::_Xlen();
282         }
283
284     static void __cdecl _Xran()
285         {
286         _Mystring::_Xran();
287         }
288
289     static void __cdecl _Xinvarg()
290         {
291         _Mystring::_Xinvarg();
292         }
293
294     pointer _Myptr;    // offset of element in string
295     };
296
297 template<class _Elem,
298     class _Traits,
299     class _Alloc> inline
300     _String_const_iterator<_Elem, _Traits, _Alloc> __CLRCALL_OR_CDECL operator+(
301         typename _String_const_iterator<_Elem, _Traits, _Alloc>
302             ::difference_type _Off,
303         _String_const_iterator<_Elem, _Traits, _Alloc> _Next)
304     {    // add offset to iterator
305     return (_Next += _Off);
306     }
307
308         // TEMPLATE CLASS _String_iterator
309 template<class _Elem,
310     class _Traits,
311     class _Alloc>
312     class _String_iterator
313         : public _String_const_iterator<_Elem, _Traits, _Alloc>
314     {    // iterator for mutable string
315 public:
316     typedef _String_iterator<_Elem, _Traits, _Alloc> _Myt;
317     typedef _String_const_iterator<_Elem, _Traits, _Alloc> _Mybase;
318
319     typedef random_access_iterator_tag iterator_category;
320     typedef _Elem value_type;
321     typedef typename _Alloc::difference_type difference_type;
322     typedef typename _Alloc::pointer pointer;
323     typedef typename _Alloc::reference reference;
324
325     __CLR_OR_THIS_CALL _String_iterator()
326         {    // construct with null string pointer
327         }
328
329  #if _HAS_ITERATOR_DEBUGGING
330  #define _STRING_ITERATOR(ptr)    iterator(ptr, this)
331
332     __CLR_OR_THIS_CALL _String_iterator(pointer _Ptr, const _Container_base_secure *_Pstring)
333         : _Mybase(_Ptr, _Pstring)
334         {    // construct with pointer _Ptr
335         }
336
337   #elif _SECURE_SCL
338  #define _STRING_ITERATOR(ptr)    iterator(ptr, this)
339         __CLR_OR_THIS_CALL _String_iterator(pointer _Ptr, const _Container_base_secure *_Pstring)
340             : _Mybase(_Ptr, _Pstring)
341             {    // construct with pointer _Ptr
342             }
343
344  #else /* _HAS_ITERATOR_DEBUGGING */
345  #define _STRING_ITERATOR(ptr)    iterator(ptr)
346
347     __CLR_OR_THIS_CALL _String_iterator(pointer _Ptr)
348         : _Mybase(_Ptr)
349         {    // construct with pointer _Ptr
350         }
351  #endif /* _HAS_ITERATOR_DEBUGGING */
352
353 #if _SECURE_SCL && !_HAS_ITERATOR_DEBUGGING
354     typedef pointer _Checked_iterator_base_type;
355
356     _Checked_iterator_base_type _Checked_iterator_base() const
357     {
358         return const_cast<pointer>(this->_Myptr);
359     }
360
361     void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
362     {
363         this->_Myptr = _Base;
364     }
365 #endif
366
367     reference __CLR_OR_THIS_CALL operator*() const
368         {    // return designated object
369         return ((reference)**(_Mybase *)this);
370         }
371
372     pointer __CLR_OR_THIS_CALL operator->() const
373         {    // return pointer to class object
374         return (&**this);
375         }
376
377     _Myt& __CLR_OR_THIS_CALL operator++()
378         {    // preincrement
379         ++(*(_Mybase *)this);
380         return (*this);
381         }
382
383     _Myt __CLR_OR_THIS_CALL operator++(int)
384         {    // postincrement
385         _Myt _Tmp = *this;
386         ++*this;
387         return (_Tmp);
388         }
389
390     _Myt& __CLR_OR_THIS_CALL operator--()
391         {    // predecrement
392         --(*(_Mybase *)this);
393         return (*this);
394         }
395
396     _Myt __CLR_OR_THIS_CALL operator--(int)
397         {    // postdecrement
398         _Myt _Tmp = *this;
399         --*this;
400         return (_Tmp);
401         }
402
403     _Myt& __CLR_OR_THIS_CALL operator+=(difference_type _Off)
404         {    // increment by integer
405         (*(_Mybase *)this) += _Off;
406         return (*this);
407         }
408
409     _Myt __CLR_OR_THIS_CALL operator+(difference_type _Off) const
410         {    // return this + integer
411         _Myt _Tmp = *this;
412         return (_Tmp += _Off);
413         }
414
415     _Myt& __CLR_OR_THIS_CALL operator-=(difference_type _Off)
416         {    // decrement by integer
417         return (*this += -_Off);
418         }
419
420     _Myt __CLR_OR_THIS_CALL operator-(difference_type _Off) const
421         {    // return this - integer
422         _Myt _Tmp = *this;
423         return (_Tmp -= _Off);
424         }
425
426     difference_type __CLR_OR_THIS_CALL operator-(const _Mybase& _Right) const
427         {    // return difference of iterators
428         return ((_Mybase)*this - _Right);
429         }
430
431     reference __CLR_OR_THIS_CALL operator[](difference_type _Off) const
432         {    // subscript
433         return (*(*this + _Off));
434         }
435     };
436
437 template<class _Elem,
438     class _Traits,
439     class _Alloc> inline
440     _String_iterator<_Elem, _Traits, _Alloc> __CLR_OR_THIS_CALL operator+(
441         typename _String_iterator<_Elem, _Traits, _Alloc>
442             ::difference_type _Off,
443         _String_iterator<_Elem, _Traits, _Alloc> _Next)
444     {    // add offset to iterator
445     return (_Next += _Off);
446     }
447
448         // CLASS _String_base
449 class _CRTIMP2_PURE _String_base
450         : public _Container_base_secure
451     {    // ultimate base class for basic_string to hold error reporters
452 public:
453     _MRTIMP2_NPURE_NCEEPURE static void __CLRCALL_PURE_OR_CDECL _Xlen();    // report a length_error
454
455     _MRTIMP2_NPURE_NCEEPURE static void __CLRCALL_PURE_OR_CDECL _Xran();    // report an out_of_range error
456
457     _MRTIMP2_NPURE_NCEEPURE static void __CLRCALL_PURE_OR_CDECL _Xinvarg();
458     };
459
460         // TEMPLATE CLASS _String_val
461 template<class _Ty,
462     class _Alloc>
463     class _String_val
464         : public _String_base
465     {    // base class for basic_string to hold allocator _Alval
466 protected:
467     typedef typename _Alloc::template
468         rebind<_Ty>::other _Alty;
469
470     __CLR_OR_THIS_CALL _String_val(_Alty _Al = _Alty())
471         : _Alval(_Al)
472         {    // construct allocator from _Al
473         }
474
475 public:
476     __CLR_OR_THIS_CALL _String_val(const _String_val &_Right)
477         : _Alval(_Right._Alval)
478         {    // copy constructor
479 #if defined(_DEBUG)
480         if (_Right._Myfirstiter == _IGNORE_MYITERLIST)
481             {
482             this->_Myfirstiter = _IGNORE_MYITERLIST;
483             }
484 #endif
485         }
486
487 protected:
488     _Alty _Alval;    // allocator object for strings
489     };
490
491         // TEMPLATE CLASS basic_string
492 template<class _Elem,
493     class _Traits,
494     class _Ax>
495     class basic_string
496         : public _String_val<_Elem, _Ax>
497     {    // null-terminated transparent array of elements
498 public:
499     typedef basic_string<_Elem, _Traits, _Ax> _Myt;
500     typedef _String_val<_Elem, _Ax> _Mybase;
501     typedef typename _Mybase::_Alty _Alloc;
502     typedef typename _Alloc::size_type size_type;
503     typedef typename _Alloc::difference_type _Dift;
504     typedef _Dift difference_type;
505     typedef typename _Alloc::pointer _Tptr;
506     typedef typename _Alloc::const_pointer _Ctptr;
507     typedef _Tptr pointer;
508     typedef _Ctptr const_pointer;
509     typedef typename _Alloc::reference _Reft;
510     typedef _Reft reference;
511     typedef typename _Alloc::const_reference const_reference;
512     typedef typename _Alloc::value_type value_type;
513
514 #define _STR_ITER_BASE(it)    (it)._Myptr
515
516     typedef _String_iterator<_Elem, _Traits, _Alloc> iterator;
517     typedef _String_const_iterator<_Elem, _Traits, _Alloc> const_iterator;
518
519 //    friend class _String_iterator<_Elem, _Traits, _Alloc>;
520     friend class _String_const_iterator<_Elem, _Traits, _Alloc>;
521
522     typedef std::reverse_iterator<iterator> reverse_iterator;
523     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
524
525       #if defined(_DLL_CPPLIB)
526
527       /*
528       * This special _Size_type struct is used to overload operator[].
529       * The correct operator[] is chosen based on the value of _SECURE_SCL.
530       * See below when we define operator[].
531       */
532       #if _DEFINE_DLL_OVERLOADS || !_SECURE_SCL
533       struct _Size_type_nosscl
534       {
535       size_t _Value;
536       _Size_type_nosscl(size_t _Val): _Value(_Val) { }
537       };
538       #endif
539
540       /*
541       * _No_debug_placeholder is used to overload the basic_string constructors.
542       * The correct constructors are chosen based on the value of _HAS_ITERATOR_DEBUGGING.
543       * See below when we define the constructors.
544       */
545       #if _DEFINE_DLL_OVERLOADS || (defined(_DEBUG) && !_HAS_ITERATOR_DEBUGGING)
546     struct _No_debug_placeholder
547     {
548     };
549   #endif
550
551   #if defined(_DEBUG)
552     struct _Has_debug_it
553     {
554         bool _Value;
555         explicit _Has_debug_it(bool _Val): _Value(_Val) { }
556     };
557   #endif
558
559  #endif /* _DLL_CPPLIB */
560
561  #if !defined(_DEBUG) || !defined(_DLL_CPPLIB) || defined(_DEFINE_EMPTY_STRING_CONSTRUCTOR)
562
563     __CLR_OR_THIS_CALL basic_string()
564         : _Mybase()
565         {    // construct empty string
566         _Tidy();
567         }
568
569  #else /* defined(_DEBUG) && defined(_DLL_CPPLIB) */
570
571   #if _HAS_ITERATOR_DEBUGGING
572
573     __CLR_OR_THIS_CALL basic_string(_Has_debug_it _Hdi = _Has_debug_it(true))
574         : _Mybase()
575         {    // construct empty string
576         if (!_Hdi._Value)
577             {
578             this->_Myfirstiter = _IGNORE_MYITERLIST;
579             }
580         _Tidy();
581         }
582
583   #else
584
585     __CLR_OR_THIS_CALL basic_string(_Has_debug_it _Hdi = _Has_debug_it(false))
586         : _Mybase()
587         {    // construct empty string
588         if (!_Hdi._Value)
589             {
590             this->_Myfirstiter = _IGNORE_MYITERLIST;
591             }
592         _Tidy();
593         }
594
595   #endif
596
597  #endif /* !defined(_DEBUG) || !defined(_DLL_CPPLIB) */
598
599  #if !defined(_DEBUG) || !defined(_DLL_CPPLIB) || _HAS_ITERATOR_DEBUGGING
600
601     explicit __CLR_OR_THIS_CALL basic_string(const _Alloc& _Al)
602         : _Mybase(_Al)
603         {    // construct empty string with allocator
604         _Tidy();
605         }
606
607     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, size_type _Roff,
608         size_type _Count = npos)
609         : _Mybase()
610         {    // construct from _Right [_Roff, _Roff + _Count)
611 #if _HAS_ITERATOR_DEBUGGING
612         if (_Right._Myfirstiter == _IGNORE_MYITERLIST)
613             {
614             this->_Myfirstiter = _IGNORE_MYITERLIST;
615             }
616 #endif
617         _Tidy();
618         assign(_Right, _Roff, _Count);
619         }
620
621     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, size_type _Roff, size_type _Count,
622         const _Alloc& _Al)
623         : _Mybase(_Al)
624         {    // construct from _Right [_Roff, _Roff + _Count) with allocator
625 #if _HAS_ITERATOR_DEBUGGING
626         if (_Right._Myfirstiter == _IGNORE_MYITERLIST)
627             {
628             this->_Myfirstiter = _IGNORE_MYITERLIST;
629             }
630 #endif
631         _Tidy();
632         assign(_Right, _Roff, _Count);
633         }
634
635     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, size_type _Count)
636         : _Mybase()
637         {    // construct from [_Ptr, _Ptr + _Count)
638         _Tidy();
639         assign(_Ptr, _Count);
640         }
641
642     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al)
643         : _Mybase(_Al)
644         {    // construct from [_Ptr, _Ptr + _Count) with allocator
645         _Tidy();
646         assign(_Ptr, _Count);
647         }
648
649     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr)
650         : _Mybase()
651         {    // construct from [_Ptr, <null>)
652         _Tidy();
653         assign(_Ptr);
654         }
655
656     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, const _Alloc& _Al)
657         : _Mybase(_Al)
658         {    // construct from [_Ptr, <null>) with allocator
659         _Tidy();
660         assign(_Ptr);
661         }
662
663     __CLR_OR_THIS_CALL basic_string(size_type _Count, _Elem _Ch)
664         : _Mybase()
665         {    // construct from _Count * _Ch
666         _Tidy();
667         assign(_Count, _Ch);
668         }
669
670     __CLR_OR_THIS_CALL basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al)
671         : _Mybase(_Al)
672         {    // construct from _Count * _Ch with allocator
673         _Tidy();
674         assign(_Count, _Ch);
675         }
676
677     template<class _It>
678         __CLR_OR_THIS_CALL basic_string(_It _First, _It _Last)
679         : _Mybase()
680         {    // construct from [_First, _Last)
681         _Tidy();
682         _Construct(_First, _Last, _Iter_cat(_First));
683         }
684
685     template<class _It>
686         __CLR_OR_THIS_CALL basic_string(_It _First, _It _Last, const _Alloc& _Al)
687         : _Mybase(_Al)
688         {    // construct from [_First, _Last) with allocator
689         _Tidy();
690         _Construct(_First, _Last, _Iter_cat(_First));
691         }
692
693     __CLR_OR_THIS_CALL basic_string(const_pointer _First, const_pointer _Last)
694         : _Mybase()
695         {    // construct from [_First, _Last), const pointers
696 #if defined(_DEBUG)
697         _DEBUG_RANGE(_First, _Last);
698 #endif
699         _Tidy();
700         if (_First != _Last)
701             assign(&*_First, _Last - _First);
702         }
703
704     __CLR_OR_THIS_CALL basic_string(const_iterator _First, const_iterator _Last)
705         : _Mybase()
706         {    // construct from [_First, _Last), const_iterators
707 #if defined(_DEBUG)
708         _DEBUG_RANGE(_First, _Last);
709 #endif
710         _Tidy();
711         if (_First != _Last)
712             assign(&*_First, _Last - _First);
713         }
714
715  #endif /* !defined(_DEBUG) || !defined(_DLL_CPPLIB) || _HAS_ITERATOR_DEBUGGING */
716
717     // The copy constructor does not need to be overloaded.
718     // If _Right._Myfirstiter == _IGNORE_MYITERLIST it will be copied over.
719     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right)
720         : _Mybase(_Right)
721         {    // construct by copying _Right
722         _Tidy();
723         assign(_Right, 0, npos);
724         }
725
726  #if defined(_DEBUG) && defined(_DLL_CPPLIB)
727
728   #if _DEFINE_DLL_OVERLOADS || !_HAS_ITERATOR_DEBUGGING
729
730     explicit __CLR_OR_THIS_CALL basic_string(const _Alloc& _Al, _NO_DEBUG_PLACEHOLDER)
731         : _Mybase(_Al)
732         {    // construct empty string with allocator
733         this->_Myfirstiter = _IGNORE_MYITERLIST;
734         _Tidy();
735         }
736
737     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, _No_debug_placeholder)
738         : _Mybase(_Right._Alval)
739         {    // construct by copying _Right
740         this->_Myfirstiter = _IGNORE_MYITERLIST;
741         _Tidy();
742         assign(_Right, 0, npos);
743         }
744
745     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, size_type _Roff, _NO_DEBUG_PLACEHOLDER)
746         : _Mybase(_Right._Alval)
747         {    // construct from _Right [_Roff, _Roff + _Count)
748         this->_Myfirstiter = _IGNORE_MYITERLIST;
749         _Tidy();
750         assign(_Right, _Roff, npos);
751         }
752
753     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, size_type _Roff,
754         size_type _Count, _NO_DEBUG_PLACEHOLDER)
755         : _Mybase()
756         {    // construct from _Right [_Roff, _Roff + _Count)
757         this->_Myfirstiter = _IGNORE_MYITERLIST;
758         _Tidy();
759         assign(_Right, _Roff, _Count);
760         }
761
762     __CLR_OR_THIS_CALL basic_string(const _Myt& _Right, size_type _Roff, size_type _Count,
763         const _Alloc& _Al, _NO_DEBUG_PLACEHOLDER)
764         : _Mybase(_Al)
765         {    // construct from _Right [_Roff, _Roff + _Count) with allocator
766         this->_Myfirstiter = _IGNORE_MYITERLIST;
767         _Tidy();
768         assign(_Right, _Roff, _Count);
769         }
770
771     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, size_type _Count, _NO_DEBUG_PLACEHOLDER)
772         : _Mybase()
773         {    // construct from [_Ptr, _Ptr + _Count)
774         this->_Myfirstiter = _IGNORE_MYITERLIST;
775         _Tidy();
776         assign(_Ptr, _Count);
777         }
778
779     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al,
780         _NO_DEBUG_PLACEHOLDER)
781         : _Mybase(_Al)
782         {    // construct from [_Ptr, _Ptr + _Count) with allocator
783         this->_Myfirstiter = _IGNORE_MYITERLIST;
784         _Tidy();
785         assign(_Ptr, _Count);
786         }
787
788     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, _NO_DEBUG_PLACEHOLDER)
789         : _Mybase()
790         {    // construct from [_Ptr, <null>)
791         this->_Myfirstiter = _IGNORE_MYITERLIST;
792         _Tidy();
793         assign(_Ptr);
794         }
795
796     __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, const _Alloc& _Al, _NO_DEBUG_PLACEHOLDER)
797         : _Mybase(_Al)
798         {    // construct from [_Ptr, <null>) with allocator
799         this->_Myfirstiter = _IGNORE_MYITERLIST;
800         _Tidy();
801         assign(_Ptr);
802         }
803
804     __CLR_OR_THIS_CALL basic_string(size_type _Count, _Elem _Ch, _NO_DEBUG_PLACEHOLDER)
805         : _Mybase()
806         {    // construct from _Count * _Ch
807         this->_Myfirstiter = _IGNORE_MYITERLIST;
808         _Tidy();
809         assign(_Count, _Ch);
810         }
811
812     __CLR_OR_THIS_CALL basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al, _NO_DEBUG_PLACEHOLDER)
813         : _Mybase(_Al)
814         {    // construct from _Count * _Ch with allocator
815         this->_Myfirstiter = _IGNORE_MYITERLIST;
816         _Tidy();
817         assign(_Count, _Ch);
818         }
819
820     template<class _It>
821         __CLR_OR_THIS_CALL basic_string(_It _First, _It _Last, _NO_DEBUG_PLACEHOLDER)
822         : _Mybase()
823         {    // construct from [_First, _Last)
824         this->_Myfirstiter = _IGNORE_MYITERLIST;
825         _Tidy();
826         _Construct(_First, _Last, _Iter_cat(_First));
827         }
828
829     template<class _It>
830         __CLR_OR_THIS_CALL basic_string(_It _First, _It _Last, const _Alloc& _Al, _NO_DEBUG_PLACEHOLDER)
831         : _Mybase(_Al)
832         {    // construct from [_First, _Last) with allocator
833         this->_Myfirstiter = _IGNORE_MYITERLIST;
834         _Tidy();
835         _Construct(_First, _Last, _Iter_cat(_First));
836         }
837
838     __CLR_OR_THIS_CALL basic_string(const_pointer _First, const_pointer _Last, _NO_DEBUG_PLACEHOLDER)
839         : _Mybase()
840         {    // construct from [_First, _Last), const pointers
841         this->_Myfirstiter = _IGNORE_MYITERLIST;
842         _Tidy();
843         if (_First != _Last)
844             assign(&*_First, _Last - _First);
845         }
846
847     __CLR_OR_THIS_CALL basic_string(const_iterator _First, const_iterator _Last, _NO_DEBUG_PLACEHOLDER)
848         : _Mybase()
849         {    // construct from [_First, _Last), const_iterators
850         this->_Myfirstiter = _IGNORE_MYITERLIST;
851         _Tidy();
852         if (_First != _Last)
853             assign(&*_First, _Last - _First);
854         }
855
856   #endif /* _DEFINE_DLL_OVERLOADS || !_HAS_ITERATOR_DEBUGGING */
857
858  #endif /* defined(_DEBUG) && defined(_DLL_CPPLIB) */
859
860     template<class _It>
861         void __CLR_OR_THIS_CALL _Construct(_It _Count,
862             _It _Ch, _Int_iterator_tag)
863         {    // initialize from _Count * _Ch
864         assign((size_type)_Count, (_Elem)_Ch);
865         }
866
867     template<class _It>
868         void __CLR_OR_THIS_CALL _Construct(_It _First,
869             _It _Last, input_iterator_tag)
870         {    // initialize from [_First, _Last), input iterators
871         _TRY_BEGIN
872         for (; _First != _Last; ++_First)
873             append((size_type)1, (_Elem)*_First);
874         _CATCH_ALL
875         _Tidy(true);
876         _RERAISE;
877         _CATCH_END
878         }
879
880     template<class _It>
881         void __CLR_OR_THIS_CALL _Construct(_It _First,
882             _It _Last, forward_iterator_tag)
883         {    // initialize from [_First, _Last), forward iterators
884 #if defined(_DEBUG)
885         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
886         if (this->_Myfirstiter != _IGNORE_MYITERLIST)
887             {
888             _DEBUG_RANGE(_First, _Last);
889             }
890 #endif
891         size_type _Count = 0;
892         _Distance(_First, _Last, _Count);
893         reserve(_Count);
894
895         _TRY_BEGIN
896         for (; _First != _Last; ++_First)
897             append((size_type)1, (_Elem)*_First);
898         _CATCH_ALL
899         _Tidy(true);
900         _RERAISE;
901         _CATCH_END
902         }
903
904     __CLR_OR_THIS_CALL ~basic_string()
905         {    // destroy the string
906         _Tidy(true);
907         }
908
909     typedef _Traits traits_type;
910     typedef _Alloc allocator_type;
911
912     _PGLOBAL static const size_type npos;    // generic bad/missing length/position
913
914     _Myt& __CLR_OR_THIS_CALL operator=(const _Myt& _Right)
915         {    // assign _Right
916         return (assign(_Right));
917         }
918
919     _Myt& __CLR_OR_THIS_CALL operator=(const _Elem *_Ptr)
920         {    // assign [_Ptr, <null>)
921         return (assign(_Ptr));
922         }
923
924     _Myt& __CLR_OR_THIS_CALL operator=(_Elem _Ch)
925         {    // assign 1 * _Ch
926         return (assign(1, _Ch));
927         }
928
929     _Myt& __CLR_OR_THIS_CALL operator+=(const _Myt& _Right)
930         {    // append _Right
931         return (append(_Right));
932         }
933
934     _Myt& __CLR_OR_THIS_CALL operator+=(const _Elem *_Ptr)
935         {    // append [_Ptr, <null>)
936         return (append(_Ptr));
937         }
938
939     _Myt& __CLR_OR_THIS_CALL operator+=(_Elem _Ch)
940         {    // append 1 * _Ch
941         return (append((size_type)1, _Ch));
942         }
943
944     _Myt& __CLR_OR_THIS_CALL append(const _Myt& _Right)
945         {    // append _Right
946         return (append(_Right, 0, npos));
947         }
948
949     _Myt& __CLR_OR_THIS_CALL append(const _Myt& _Right,
950         size_type _Roff, size_type _Count)
951         {    // append _Right [_Roff, _Roff + _Count)
952         if (_Right.size() < _Roff)
953             _String_base::_Xran();    // _Roff off end
954         size_type _Num = _Right.size() - _Roff;
955         if (_Num < _Count)
956             _Count = _Num;    // trim _Count to size
957         if (npos - _Mysize <= _Count || _Mysize + _Count < _Mysize)
958             _String_base::_Xlen();    // result too long
959
960         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
961             {    // make room and append new stuff
962             _Traits_helper::copy_s<_Traits>(_Myptr() + _Mysize, _Myres - _Mysize,
963                 _Right._Myptr() + _Roff, _Count);
964             _Eos(_Num);
965             }
966         return (*this);
967         }
968
969     _Myt& __CLR_OR_THIS_CALL append(const _Elem *_Ptr, size_type _Count)
970         {    // append [_Ptr, _Ptr + _Count)
971
972  #if _HAS_ITERATOR_DEBUGGING
973         if (_Count != 0)
974             _DEBUG_POINTER(_Ptr);
975  #endif /* _HAS_ITERATOR_DEBUGGING */
976
977         if (_Inside(_Ptr))
978             return (append(*this, _Ptr - _Myptr(), _Count));    // substring
979         if (npos - _Mysize <= _Count || _Mysize + _Count < _Mysize)
980             _String_base::_Xlen();    // result too long
981
982         size_type _Num;
983         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
984             {    // make room and append new stuff
985             _Traits_helper::copy_s<_Traits>(_Myptr() + _Mysize, _Myres - _Mysize, _Ptr, _Count);
986             _Eos(_Num);
987             }
988         return (*this);
989         }
990
991     _Myt& __CLR_OR_THIS_CALL append(const _Elem *_Ptr)
992         {    // append [_Ptr, <null>)
993         _DEBUG_POINTER(_Ptr);
994         return (append(_Ptr, _Traits::length(_Ptr)));
995         }
996
997     _Myt& __CLR_OR_THIS_CALL append(size_type _Count, _Elem _Ch)
998         {    // append _Count * _Ch
999             if (npos - _Mysize <= _Count)
1000             _String_base::_Xlen();    // result too long
1001
1002         size_type _Num;
1003         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
1004             {    // make room and append new stuff using assign
1005             _Chassign(_Mysize, _Count, _Ch);
1006             _Eos(_Num);
1007             }
1008         return (*this);
1009         }
1010
1011     template<class _It>
1012         _Myt& __CLR_OR_THIS_CALL append(_It _First, _It _Last)
1013         {    // append [_First, _Last)
1014         return (_Append(_First, _Last, _Iter_cat(_First)));
1015         }
1016
1017     template<class _It>
1018         _Myt& __CLR_OR_THIS_CALL _Append(_It _Count, _It _Ch, _Int_iterator_tag)
1019         {    // append _Count * _Ch
1020         return (append((size_type)_Count, (_Elem)_Ch));
1021         }
1022
1023     template<class _It>
1024         _Myt& __CLR_OR_THIS_CALL _Append(_It _First, _It _Last, input_iterator_tag)
1025         {    // append [_First, _Last), input iterators
1026         return (replace(end(), end(), _First, _Last));
1027         }
1028
1029     _Myt& __CLR_OR_THIS_CALL append(const_pointer _First, const_pointer _Last)
1030         {    // append [_First, _Last), const pointers
1031         return (replace(end(), end(), _First, _Last));
1032         }
1033
1034     _Myt& __CLR_OR_THIS_CALL append(const_iterator _First, const_iterator _Last)
1035         {    // append [_First, _Last), const_iterators
1036         return (replace(end(), end(), _First, _Last));
1037         }
1038
1039     _Myt& __CLR_OR_THIS_CALL assign(const _Myt& _Right)
1040         {    // assign _Right
1041         return (assign(_Right, 0, npos));
1042         }
1043
1044     _Myt& __CLR_OR_THIS_CALL assign(const _Myt& _Right,
1045         size_type _Roff, size_type _Count)
1046         {    // assign _Right [_Roff, _Roff + _Count)
1047         if (_Right.size() < _Roff)
1048             _String_base::_Xran();    // _Roff off end
1049         size_type _Num = _Right.size() - _Roff;
1050         if (_Count < _Num)
1051             _Num = _Count;    // trim _Num to size
1052
1053         if (this == &_Right)
1054             erase((size_type)(_Roff + _Num)), erase(0, _Roff);    // substring
1055         else if (_Grow(_Num))
1056             {    // make room and assign new stuff
1057             _Traits_helper::copy_s<_Traits>(_Myptr(), _Myres, _Right._Myptr() + _Roff, _Num);
1058             _Eos(_Num);
1059             }
1060         return (*this);
1061         }
1062
1063     _Myt& __CLR_OR_THIS_CALL assign(const _Elem *_Ptr, size_type _Count)
1064         {    // assign [_Ptr, _Ptr + _Count)
1065
1066  #if _HAS_ITERATOR_DEBUGGING
1067         if (_Count != 0)
1068             _DEBUG_POINTER(_Ptr);
1069  #endif /* _HAS_ITERATOR_DEBUGGING */
1070
1071         if (_Inside(_Ptr))
1072             return (assign(*this, _Ptr - _Myptr(), _Count));    // substring
1073
1074         if (_Grow(_Count))
1075             {    // make room and assign new stuff
1076             _Traits_helper::copy_s<_Traits>(_Myptr(), _Myres, _Ptr, _Count);
1077             _Eos(_Count);
1078             }
1079         return (*this);
1080         }
1081
1082     _Myt& __CLR_OR_THIS_CALL assign(const _Elem *_Ptr)
1083         {    // assign [_Ptr, <null>)
1084         _DEBUG_POINTER(_Ptr);
1085         return (assign(_Ptr, _Traits::length(_Ptr)));
1086         }
1087
1088     _Myt& __CLR_OR_THIS_CALL assign(size_type _Count, _Elem _Ch)
1089         {    // assign _Count * _Ch
1090         if (_Count == npos)
1091             _String_base::_Xlen();    // result too long
1092
1093         if (_Grow(_Count))
1094             {    // make room and assign new stuff
1095             _Chassign(0, _Count, _Ch);
1096             _Eos(_Count);
1097             }
1098         return (*this);
1099         }
1100
1101     template<class _It>
1102         _Myt& __CLR_OR_THIS_CALL assign(_It _First, _It _Last)
1103         {    // assign [First, _Last)
1104         return (_Assign(_First, _Last, _Iter_cat(_First)));
1105         }
1106
1107     template<class _It>
1108         _Myt& __CLR_OR_THIS_CALL _Assign(_It _Count, _It _Ch, _Int_iterator_tag)
1109         {    // assign _Count * _Ch
1110         return (assign((size_type)_Count, (_Elem)_Ch));
1111         }
1112
1113     template<class _It>
1114         _Myt& __CLR_OR_THIS_CALL _Assign(_It _First, _It _Last, input_iterator_tag)
1115         {    // assign [First, _Last), input iterators
1116         return (replace(begin(), end(), _First, _Last));
1117         }
1118
1119     _Myt& __CLR_OR_THIS_CALL assign(const_pointer _First, const_pointer _Last)
1120         {    // assign [First, _Last), const pointers
1121         return (replace(begin(), end(), _First, _Last));
1122         }
1123
1124     _Myt& __CLR_OR_THIS_CALL assign(const_iterator _First, const_iterator _Last)
1125         {    // assign [First, _Last), const_iterators
1126         return (replace(begin(), end(), _First, _Last));
1127         }
1128
1129     _Myt& __CLR_OR_THIS_CALL insert(size_type _Off, const _Myt& _Right)
1130         {    // insert _Right at _Off
1131         return (insert(_Off, _Right, 0, npos));
1132         }
1133
1134     _Myt& __CLR_OR_THIS_CALL insert(size_type _Off,
1135         const _Myt& _Right, size_type _Roff, size_type _Count)
1136         {    // insert _Right [_Roff, _Roff + _Count) at _Off
1137         if (_Mysize < _Off || _Right.size() < _Roff)
1138             _String_base::_Xran();    // _Off or _Roff off end
1139         size_type _Num = _Right.size() - _Roff;
1140         if (_Num < _Count)
1141             _Count = _Num;    // trim _Count to size
1142         if (npos - _Mysize <= _Count)
1143             _String_base::_Xlen();    // result too long
1144
1145         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
1146             {    // make room and insert new stuff
1147             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1148                 _Myptr() + _Off, _Mysize - _Off);    // empty out hole
1149             if (this == &_Right)
1150                 _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1151                     _Myptr() + (_Off < _Roff ? _Roff + _Count : _Roff),
1152                         _Count);    // substring
1153             else
1154                 _Traits_helper::copy_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1155                     _Right._Myptr() + _Roff, _Count);    // fill hole
1156             _Eos(_Num);
1157             }
1158         return (*this);
1159         }
1160
1161     _Myt& __CLR_OR_THIS_CALL insert(size_type _Off,
1162         const _Elem *_Ptr, size_type _Count)
1163         {    // insert [_Ptr, _Ptr + _Count) at _Off
1164
1165  #if _HAS_ITERATOR_DEBUGGING
1166         if (_Count != 0)
1167             _DEBUG_POINTER(_Ptr);
1168  #endif /* _HAS_ITERATOR_DEBUGGING */
1169
1170         if (_Inside(_Ptr))
1171             return (insert(_Off, *this,
1172                 _Ptr - _Myptr(), _Count));    // substring
1173         if (_Mysize < _Off)
1174             _String_base::_Xran();    // _Off off end
1175         if (npos - _Mysize <= _Count)
1176             _String_base::_Xlen();    // result too long
1177         size_type _Num;
1178         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
1179             {    // make room and insert new stuff
1180             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1181                 _Myptr() + _Off, _Mysize - _Off);    // empty out hole
1182             _Traits_helper::copy_s<_Traits>(_Myptr() + _Off, _Myres - _Off, _Ptr, _Count);    // fill hole
1183             _Eos(_Num);
1184             }
1185         return (*this);
1186         }
1187
1188     _Myt& __CLR_OR_THIS_CALL insert(size_type _Off, const _Elem *_Ptr)
1189         {    // insert [_Ptr, <null>) at _Off
1190         _DEBUG_POINTER(_Ptr);
1191         return (insert(_Off, _Ptr, _Traits::length(_Ptr)));
1192         }
1193
1194     _Myt& __CLR_OR_THIS_CALL insert(size_type _Off,
1195         size_type _Count, _Elem _Ch)
1196         {    // insert _Count * _Ch at _Off
1197         if (_Mysize < _Off)
1198             _String_base::_Xran();    // _Off off end
1199         if (npos - _Mysize <= _Count)
1200             _String_base::_Xlen();    // result too long
1201         size_type _Num;
1202         if (0 < _Count && _Grow(_Num = _Mysize + _Count))
1203             {    // make room and insert new stuff
1204             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1205                 _Myptr() + _Off, _Mysize - _Off);    // empty out hole
1206             _Chassign(_Off, _Count, _Ch);    // fill hole
1207             _Eos(_Num);
1208             }
1209         return (*this);
1210         }
1211
1212     iterator __CLR_OR_THIS_CALL insert(const_iterator _Where)
1213         {    // insert <null> at _Where
1214         return (insert(_Where, _Elem()));
1215         }
1216
1217     iterator __CLR_OR_THIS_CALL insert(const_iterator _Where, _Elem _Ch)
1218         {    // insert _Ch at _Where
1219         size_type _Off = _Pdif(_Where, begin());
1220         insert(_Off, 1, _Ch);
1221         return (begin() + _Off);
1222         }
1223
1224     void __CLR_OR_THIS_CALL insert(const_iterator _Where, size_type _Count, _Elem _Ch)
1225         {    // insert _Count * _Elem at _Where
1226         size_type _Off = _Pdif(_Where, begin());
1227         insert(_Off, _Count, _Ch);
1228         }
1229
1230     template<class _It>
1231         void __CLR_OR_THIS_CALL insert(const_iterator _Where, _It _First, _It _Last)
1232         {    // insert [_First, _Last) at _Where
1233         _Insert(_Where, _First, _Last, _Iter_cat(_First));
1234         }
1235
1236     template<class _It>
1237         void __CLR_OR_THIS_CALL _Insert(const_iterator _Where, _It _Count, _It _Ch,
1238             _Int_iterator_tag)
1239         {    // insert _Count * _Ch at _Where
1240         insert(_Where, (size_type)_Count, (_Elem)_Ch);
1241         }
1242
1243     template<class _It>
1244         void __CLR_OR_THIS_CALL _Insert(const_iterator _Where, _It _First, _It _Last,
1245             input_iterator_tag)
1246         {    // insert [_First, _Last) at _Where, input iterators
1247         replace(_Where, _Where, _First, _Last);
1248         }
1249
1250     void __CLR_OR_THIS_CALL insert(const_iterator _Where, const_pointer _First, const_pointer _Last)
1251         {    // insert [_First, _Last) at _Where, const pointers
1252         replace(_Where, _Where, _First, _Last);
1253         }
1254
1255     void __CLR_OR_THIS_CALL insert(const_iterator _Where, const_iterator _First, const_iterator _Last)
1256         {    // insert [_First, _Last) at _Where, const_iterators
1257         replace(_Where, _Where, _First, _Last);
1258         }
1259
Lines 1260 ... 1269 are skipped.
1270                 _Mysize - _Off - _Count);
1271             size_type _Newsize = _Mysize - _Count;
1272             _Eos(_Newsize);
1273             }
1274         return (*this);
1275         }
1276
1277     iterator __CLR_OR_THIS_CALL erase(const_iterator _Where)
1278         {    // erase element at _Where
1279         size_type _Count = _Pdif(_Where, begin());
1280         erase(_Count, 1);
1281         return (_STRING_ITERATOR(_Myptr() + _Count));
1282         }
1283
1284     iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last)
1285         {    // erase substring [_First, _Last)
1286         size_type _Count = _Pdif(_First, begin());
1287         erase(_Count, _Pdif(_Last, _First));
1288         return (_STRING_ITERATOR(_Myptr() + _Count));
1289         }
1290
1291     void __CLR_OR_THIS_CALL clear()
1292         {    // erase all
1293         erase(begin(), end());
1294         }
1295
1296     _Myt& __CLR_OR_THIS_CALL replace(size_type _Off, size_type _N0, const _Myt& _Right)
1297         {    // replace [_Off, _Off + _N0) with _Right
1298         return (replace(_Off, _N0, _Right, 0, npos));
1299         }
1300
1301     _Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
1302         size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
1303         {    // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
1304         if (_Mysize < _Off || _Right.size() < _Roff)
1305             _String_base::_Xran();    // _Off or _Roff off end
1306         if (_Mysize - _Off < _N0)
1307             _N0 = _Mysize - _Off;    // trim _N0 to size
1308         size_type _Num = _Right.size() - _Roff;
1309         if (_Num < _Count)
1310             _Count = _Num;    // trim _Count to size
1311         if (npos - _Count <= _Mysize - _N0)
1312             _String_base::_Xlen();    // result too long
1313
1314         size_type _Nm = _Mysize - _N0 - _Off;    // length of preserved tail
1315         size_type _Newsize = _Mysize + _Count - _N0;
1316         if (_Mysize < _Newsize)
1317             _Grow(_Newsize);
1318
1319         if (this != &_Right)
1320             {    // no overlap, just move down and copy in new stuff
1321             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1322                 _Myptr() + _Off + _N0, _Nm);    // empty hole
1323             _Traits_helper::copy_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1324                 _Right._Myptr() + _Roff, _Count);    // fill hole
1325             }
1326         else if (_Count <= _N0)
1327             {    // hole doesn't get larger, just copy in substring
1328             _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1329                 _Myptr() + _Roff, _Count);    // fill hole
1330             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1331                 _Myptr() + _Off + _N0, _Nm);    // move tail down
1332             }
1333         else if (_Roff <= _Off)
1334             {    // hole gets larger, substring begins before hole
1335             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1336                 _Myptr() + _Off + _N0, _Nm);    // move tail down
1337             _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1338                 _Myptr() + _Roff, _Count);    // fill hole
1339             }
1340         else if (_Off + _N0 <= _Roff)
1341             {    // hole gets larger, substring begins after hole
1342             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1343                 _Myptr() + _Off + _N0, _Nm);    // move tail down
1344             _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1345                 _Myptr() + (_Roff + _Count - _N0), _Count);    // fill hole
1346             }
1347         else
1348             {    // hole gets larger, substring begins in hole
1349             _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
1350                 _Myptr() + _Roff, _N0);    // fill old hole
1351             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1352                 _Myptr() + _Off + _N0, _Nm);    // move tail down
1353             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _N0, _Myres - _Off - _N0, _Myptr() + _Roff + _Count,
1354                 _Count - _N0);    // fill rest of new hole
1355             }
1356
1357         _Eos(_Newsize);
1358         return (*this);
1359         }
1360
1361     _Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
1362         size_type _N0, const _Elem *_Ptr, size_type _Count)
1363         {    // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
1364
1365  #if _HAS_ITERATOR_DEBUGGING
1366         if (_Count != 0)
1367             _DEBUG_POINTER(_Ptr);
1368  #endif /* _HAS_ITERATOR_DEBUGGING */
1369
1370         if (_Inside(_Ptr))
1371             return (replace(_Off, _N0, *this,
1372                 _Ptr - _Myptr(), _Count));    // substring, replace carefully
1373         if (_Mysize < _Off)
1374             _String_base::_Xran();    // _Off off end
1375         if (_Mysize - _Off < _N0)
1376             _N0 = _Mysize - _Off;    // trim _N0 to size
1377         if (npos - _Count <= _Mysize - _N0)
1378             _String_base::_Xlen();    // result too long
1379         size_type _Nm = _Mysize - _N0 - _Off;
1380
1381         if (_Count < _N0)
1382             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1383                 _Myptr() + _Off + _N0, _Nm);    // smaller hole, move tail up
1384         size_type _Num;
1385         if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0))
1386             {    // make room and rearrange
1387             if (_N0 < _Count)
1388                 _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1389                     _Myptr() + _Off + _N0, _Nm);    // move tail down
1390             _Traits_helper::copy_s<_Traits>(_Myptr() + _Off, _Myres - _Off, _Ptr, _Count);    // fill hole
1391             _Eos(_Num);
1392             }
1393         return (*this);
1394         }
1395
1396     _Myt& __CLR_OR_THIS_CALL replace(size_type _Off, size_type _N0, const _Elem *_Ptr)
1397         {    // replace [_Off, _Off + _N0) with [_Ptr, <null>)
1398         _DEBUG_POINTER(_Ptr);
1399         return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
1400         }
1401
1402     _Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
1403         size_type _N0, size_type _Count, _Elem _Ch)
1404         {    // replace [_Off, _Off + _N0) with _Count * _Ch
1405         if (_Mysize < _Off)
1406             _String_base::_Xran();    // _Off off end
1407         if (_Mysize - _Off < _N0)
1408             _N0 = _Mysize - _Off;    // trim _N0 to size
1409         if (npos - _Count <= _Mysize - _N0)
1410             _String_base::_Xlen();    // result too long
1411         size_type _Nm = _Mysize - _N0 - _Off;
1412
1413         if (_Count < _N0)
1414             _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1415                 _Myptr() + _Off + _N0, _Nm);    // smaller hole, move tail up
1416         size_type _Num;
1417         if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0))
1418             {    // make room and rearrange
1419             if (_N0 < _Count)
1420                 _Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
1421                     _Myptr() + _Off + _N0, _Nm);    // move tail down
1422             _Chassign(_Off, _Count, _Ch);    // fill hole
1423             _Eos(_Num);
1424             }
1425         return (*this);
1426         }
1427
1428     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last, const _Myt& _Right)
1429         {    // replace [_First, _Last) with _Right
1430         return (replace(
1431             _Pdif(_First, begin()), _Pdif(_Last, _First), _Right));
1432         }
1433
1434     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last, const _Elem *_Ptr,
1435         size_type _Count)
1436         {    // replace [_First, _Last) with [_Ptr, _Ptr + _Count)
1437         return (replace(
1438             _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count));
1439         }
1440
1441     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last, const _Elem *_Ptr)
1442         {    // replace [_First, _Last) with [_Ptr, <null>)
1443         return (replace(
1444             _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr));
1445         }
1446
1447     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last,
1448         size_type _Count, _Elem _Ch)
1449         {    // replace [_First, _Last) with _Count * _Ch
1450         return (replace(
1451             _Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch));
1452         }
1453
1454     template<class _It>
1455         _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last,
1456             _It _First2, _It _Last2)
1457         {    // replace [_First, _Last) with [_First2, _Last2)
1458         return (_Replace(_First, _Last,
1459             _First2, _Last2, _Iter_cat(_First2)));
1460         }
1461
1462     template<class _It>
1463         _Myt& __CLR_OR_THIS_CALL _Replace(const_iterator _First, const_iterator _Last,
1464             _It _Count, _It _Ch, _Int_iterator_tag)
1465         {    // replace [_First, _Last) with _Count * _Ch
1466         return (replace(_First, _Last, (size_type)_Count, (_Elem)_Ch));
1467         }
1468
1469     template<class _It>
1470         _Myt& __CLR_OR_THIS_CALL _Replace(const_iterator _First, const_iterator _Last,
1471             _It _First2, _It _Last2, input_iterator_tag)
1472         {    // replace [_First, _Last) with [_First2, _Last2), input iterators
1473         _Myt _Right(_First2, _Last2);
1474         replace(_First, _Last, _Right);
1475         return (*this);
1476         }
1477
1478     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last,
1479         const_pointer _First2, const_pointer _Last2)
1480         {    // replace [_First, _Last) with [_First2, _Last2), const pointers
1481         if (_First2 == _Last2)
1482             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
1483         else
1484             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
1485                 &*_First2, _Last2 - _First2);
1486         return (*this);
1487         }
1488
1489     _Myt& __CLR_OR_THIS_CALL replace(const_iterator _First, const_iterator _Last,
1490         const_iterator _First2, const_iterator _Last2)
1491         {    // replace [_First, _Last) with [_First2, _Last2), const_iterators
1492         if (_First2 == _Last2)
1493             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
1494         else
1495             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
1496                 &*_First2, _Last2 - _First2);
1497         return (*this);
1498         }
1499
1500     iterator __CLR_OR_THIS_CALL begin()
1501         {    // return iterator for beginning of mutable sequence
1502         return (_STRING_ITERATOR(_Myptr()));
1503         }
1504
1505     const_iterator __CLR_OR_THIS_CALL begin() const
1506         {    // return iterator for beginning of nonmutable sequence
1507         return (_STRING_CONST_ITERATOR(_Myptr()));
1508         }
1509
1510     iterator __CLR_OR_THIS_CALL end()
1511         {    // return iterator for end of mutable sequence
1512         return (_STRING_ITERATOR(_Myptr() + _Mysize));
1513         }
1514
1515     const_iterator __CLR_OR_THIS_CALL end() const
1516         {    // return iterator for end of nonmutable sequence
1517         return (_STRING_CONST_ITERATOR(_Myptr() + _Mysize));
1518         }
1519
1520     reverse_iterator __CLR_OR_THIS_CALL rbegin()
1521         {    // return iterator for beginning of reversed mutable sequence
1522         return (reverse_iterator(end()));
1523         }
1524
1525     const_reverse_iterator __CLR_OR_THIS_CALL rbegin() const
1526         {    // return iterator for beginning of reversed nonmutable sequence
1527         return (const_reverse_iterator(end()));
1528         }
1529
1530     reverse_iterator __CLR_OR_THIS_CALL rend()
1531         {    // return iterator for end of reversed mutable sequence
1532         return (reverse_iterator(begin()));
1533         }
1534
1535     const_reverse_iterator __CLR_OR_THIS_CALL rend() const
1536         {    // return iterator for end of reversed nonmutable sequence
1537         return (const_reverse_iterator(begin()));
1538         }
1539
1540     reference __CLR_OR_THIS_CALL at(size_type _Off)
1541         {    // subscript mutable sequence with checking
1542         if (_Mysize <= _Off)
1543             _String_base::_Xran();    // _Off off end
1544         return (_Myptr()[_Off]);
1545         }
1546
1547     const_reference __CLR_OR_THIS_CALL at(size_type _Off) const
1548         {    // subscript nonmutable sequence with checking
1549         if (_Mysize <= _Off)
1550             _String_base::_Xran();    // _Off off end
1551         return (_Myptr()[_Off]);
1552         }
1553
1554  #if !defined(_DLL_CPPLIB) || _SECURE_SCL
1555
1556     reference __CLR_OR_THIS_CALL operator[](size_type _Off)
1557         {    // subscript mutable sequence
1558
1559  #if _HAS_ITERATOR_DEBUGGING
1560         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1561         if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1562             {
1563             if (_Mysize < _Off)
1564                 {
1565                 _DEBUG_ERROR("string subscript out of range");
1566                 _SCL_SECURE_OUT_OF_RANGE;
1567                 }
1568             }
1569  #else
1570         _SCL_SECURE_VALIDATE_RANGE(_Off <= _Mysize);
1571  #endif /* _HAS_ITERATOR_DEBUGGING */
1572
1573         return (_Myptr()[_Off]);
1574         }
1575
1576     const_reference __CLR_OR_THIS_CALL operator[](size_type _Off) const
1577         {    // subscript nonmutable sequence
1578
1579  #if _HAS_ITERATOR_DEBUGGING
1580         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1581         if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1582             {
1583             if (_Mysize < _Off)    // sic
1584                 {
1585                 _DEBUG_ERROR("string subscript out of range");
1586                 _SCL_SECURE_OUT_OF_RANGE;
1587                 }
1588             }
1589  #else
1590         _SCL_SECURE_VALIDATE_RANGE(_Off <= _Mysize);
1591  #endif /* _HAS_ITERATOR_DEBUGGING */
1592
1593         return (_Myptr()[_Off]);
1594         }
1595
1596  #endif /* !defined(_DLL_CPPLIB) || _SECURE_SCL */
1597
1598  #if defined(_DLL_CPPLIB)
1599
1600   #if _DEFINE_DLL_OVERLOADS || !_SECURE_SCL
1601
1602     reference __CLR_OR_THIS_CALL operator[](_Size_type_nosscl _SpecialOff)
1603         {    // subscript mutable sequence
1604
1605         size_type _Off = (size_type)_SpecialOff._Value;
1606
1607  #if _HAS_ITERATOR_DEBUGGING
1608         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1609         if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1610             {
1611             if (_Mysize < _Off)
1612                 {
1613                 _DEBUG_ERROR("string subscript out of range");
1614                 }
1615             }
1616  #endif /* _HAS_ITERATOR_DEBUGGING */
1617
1618         return (_Myptr()[_Off]);
1619         }
1620
1621     const_reference __CLR_OR_THIS_CALL operator[](_Size_type_nosscl _SpecialOff) const
1622         {    // subscript nonmutable sequence
1623
1624         size_type _Off = (size_type)_SpecialOff._Value;
1625
1626  #if _HAS_ITERATOR_DEBUGGING
1627         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1628         if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1629             {
1630             if (_Mysize < _Off)    // sic
1631                 {
1632                 _DEBUG_ERROR("string subscript out of range");
1633                 }
1634             }
1635  #endif /* _HAS_ITERATOR_DEBUGGING */
1636
1637         return (_Myptr()[_Off]);
1638         }
1639
1640   #endif /* _DEFINE_DLL_OVERLOADS || !_SECURE_SCL */
1641
1642  #endif /* _DLL_CPPLIB */
1643
1644     void __CLR_OR_THIS_CALL push_back(_Elem _Ch)
1645         {    // insert element at end
1646         insert(end(), _Ch);
1647         }
1648
1649     const _Elem *__CLR_OR_THIS_CALL c_str() const
1650         {    // return pointer to null-terminated nonmutable array
1651         return (_Myptr());
1652         }
1653
1654     const _Elem *__CLR_OR_THIS_CALL data() const
1655         {    // return pointer to nonmutable array
1656         return (c_str());
1657         }
1658
1659     size_type __CLR_OR_THIS_CALL length() const
1660         {    // return length of sequence
1661         return (_Mysize);
1662         }
1663
1664     size_type __CLR_OR_THIS_CALL size() const
1665         {    // return length of sequence
1666         return (_Mysize);
1667         }
1668
1669     size_type __CLR_OR_THIS_CALL max_size() const
1670         {    // return maximum possible length of sequence
1671         size_type _Num = _Mybase::_Alval.max_size();
1672         return (_Num <= 1 ? 1 : _Num - 1);
1673         }
1674
1675     void __CLR_OR_THIS_CALL resize(size_type _Newsize)
1676         {    // determine new length, padding with null elements as needed
1677         resize(_Newsize, _Elem());
1678         }
1679
1680     void __CLR_OR_THIS_CALL resize(size_type _Newsize, _Elem _Ch)
1681         {    // determine new length, padding with _Ch elements as needed
1682         if (_Newsize <= _Mysize)
1683             erase(_Newsize);
1684         else
1685             append(_Newsize - _Mysize, _Ch);
1686         }
1687
1688     size_type __CLR_OR_THIS_CALL capacity() const
1689         {    // return current length of allocated storage
1690         return (_Myres);
1691         }
1692
1693     void __CLR_OR_THIS_CALL reserve(size_type _Newcap = 0)
1694         {    // determine new minimum length of allocated storage
1695         if (_Mysize <= _Newcap && _Myres != _Newcap)
1696             {    // change reservation
1697             size_type _Size = _Mysize;
1698             if (_Grow(_Newcap, true))
1699                 _Eos(_Size);
1700             }
1701         }
1702
1703     bool __CLR_OR_THIS_CALL empty() const
1704         {    // test if sequence is empty
1705         return (_Mysize == 0);
1706         }
1707
1708     _SCL_INSECURE_DEPRECATE
1709     size_type __CLR_OR_THIS_CALL copy(_Elem *_Dest,
1710         size_type _Count, size_type _Off = 0) const
1711         {    // copy [_Off, _Off + _Count) to [_Dest, _Dest + _Count)
1712
1713  #if _HAS_ITERATOR_DEBUGGING
1714         if (_Count != 0)
1715             _DEBUG_POINTER(_Dest);
1716  #endif /* _HAS_ITERATOR_DEBUGGING */
1717
1718         // assume there is enough space in _Ptr
1719         return _Copy_s(_Dest, _Count, _Count, _Off);
1720         }
1721
1722     size_type __CLR_OR_THIS_CALL _Copy_s(_Elem *_Dest, size_type _Dest_size,
1723         size_type _Count, size_type _Off = 0) const
1724         {    // copy [_Off, _Off + _Count) to [_Dest, _Dest + _Count)
1725         _DEBUG_POINTER(_Dest);
1726         if (_Mysize < _Off)
1727             _String_base::_Xran();    // _Off off end
1728         if (_Mysize - _Off < _Count)
1729             _Count = _Mysize - _Off;
1730         _Traits_helper::copy_s<_Traits>(_Dest, _Dest_size, _Myptr() + _Off, _Count);
1731         return (_Count);
1732         }
1733
1734     void __CLR_OR_THIS_CALL swap(_Myt& _Right)
1735         {    // exchange contents with _Right
1736         if (this == &_Right)
1737             ;    // same object, do nothing
1738         else if (_Mybase::_Alval == _Right._Alval)
1739             {    // same allocator, swap control information
1740
1741  #if _HAS_ITERATOR_DEBUGGING
1742             this->_Swap_all(_Right);
1743  #endif /* _HAS_ITERATOR_DEBUGGING */
1744
1745             _Bxty _Tbx = _Bx;
1746             _Bx = _Right._Bx, _Right._Bx = _Tbx;
1747
1748             size_type _Tlen = _Mysize;
1749             _Mysize = _Right._Mysize, _Right._Mysize = _Tlen;
1750
1751             size_type _Tres = _Myres;
1752             _Myres = _Right._Myres, _Right._Myres = _Tres;
1753             }
1754         else
1755             {    // different allocator, do multiple assigns
1756             _Myt _Tmp = *this;
1757
1758             *this = _Right;
1759             _Right = _Tmp;
1760             }
1761         }
1762
1763     size_type __CLR_OR_THIS_CALL find(const _Myt& _Right, size_type _Off = 0) const
1764         {    // look for _Right beginnng at or after _Off
1765         return (find(_Right._Myptr(), _Off, _Right.size()));
1766         }
1767
1768     size_type __CLR_OR_THIS_CALL find(const _Elem *_Ptr,
1769         size_type _Off, size_type _Count) const
1770         {    // look for [_Ptr, _Ptr + _Count) beginnng at or after _Off
1771
1772  #if _HAS_ITERATOR_DEBUGGING
1773         if (_Count != 0)
1774             _DEBUG_POINTER(_Ptr);
1775  #endif /* _HAS_ITERATOR_DEBUGGING */
1776
1777         if (_Count == 0 && _Off <= _Mysize)
1778             return (_Off);    // null string always matches (if inside string)
1779
1780         size_type _Nm;
1781         if (_Off < _Mysize && _Count <= (_Nm = _Mysize - _Off))
1782             {    // room for match, look for it
1783             const _Elem *_Uptr, *_Vptr;
1784             for (_Nm -= _Count - 1, _Vptr = _Myptr() + _Off;
1785                 (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0;
1786                 _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1)
1787                 if (_Traits::compare(_Uptr, _Ptr, _Count) == 0)
1788                     return (_Uptr - _Myptr());    // found a match
1789             }
1790
1791         return (npos);    // no match
1792         }
1793
1794     size_type __CLR_OR_THIS_CALL find(const _Elem *_Ptr, size_type _Off = 0) const
1795         {    // look for [_Ptr, <null>) beginnng at or after _Off
1796         _DEBUG_POINTER(_Ptr);
1797         return (find(_Ptr, _Off, _Traits::length(_Ptr)));
1798         }
1799
1800     size_type __CLR_OR_THIS_CALL find(_Elem _Ch, size_type _Off = 0) const
1801         {    // look for _Ch at or after _Off
1802         return (find((const _Elem *)&_Ch, _Off, 1));
1803         }
1804
1805     size_type __CLR_OR_THIS_CALL rfind(const _Myt& _Right, size_type _Off = npos) const
1806         {    // look for _Right beginning before _Off
1807         return (rfind(_Right._Myptr(), _Off, _Right.size()));
1808         }
1809
1810     size_type __CLR_OR_THIS_CALL rfind(const _Elem *_Ptr,
1811         size_type _Off, size_type _Count) const
1812         {    // look for [_Ptr, _Ptr + _Count) beginning before _Off
1813
1814  #if _HAS_ITERATOR_DEBUGGING
1815         if (_Count != 0)
1816             _DEBUG_POINTER(_Ptr);
1817  #endif /* _HAS_ITERATOR_DEBUGGING */
1818
1819         if (_Count == 0)
1820             return (_Off < _Mysize ? _Off : _Mysize);    // null always matches
1821         if (_Count <= _Mysize)
1822             {    // room for match, look for it
1823             const _Elem *_Uptr = _Myptr() +
1824                 (_Off < _Mysize - _Count ? _Off : _Mysize - _Count);
1825             for (; ; --_Uptr)
1826                 if (_Traits::eq(*_Uptr, *_Ptr)
1827                     && _Traits::compare(_Uptr, _Ptr, _Count) == 0)
1828                     return (_Uptr - _Myptr());    // found a match
1829                 else if (_Uptr == _Myptr())
1830                     break;    // at beginning, no more chance for match
1831             }
1832
1833         return (npos);    // no match
1834         }
1835
1836     size_type __CLR_OR_THIS_CALL rfind(const _Elem *_Ptr, size_type _Off = npos) const
1837         {    // look for [_Ptr, <null>) beginning before _Off
1838         _DEBUG_POINTER(_Ptr);
1839         return (rfind(_Ptr, _Off, _Traits::length(_Ptr)));
1840         }
1841
1842     size_type __CLR_OR_THIS_CALL rfind(_Elem _Ch, size_type _Off = npos) const
1843         {    // look for _Ch before _Off
1844         return (rfind((const _Elem *)&_Ch, _Off, 1));
1845         }
1846
1847     size_type __CLR_OR_THIS_CALL find_first_of(const _Myt& _Right,
1848         size_type _Off = 0) const
1849         {    // look for one of _Right at or after _Off
1850         return (find_first_of(_Right._Myptr(), _Off, _Right.size()));
1851         }
1852
1853     size_type __CLR_OR_THIS_CALL find_first_of(const _Elem *_Ptr,
1854         size_type _Off, size_type _Count) const
1855         {    // look for one of [_Ptr, _Ptr + _Count) at or after _Off
1856
1857  #if _HAS_ITERATOR_DEBUGGING
1858         if (_Count != 0)
1859             _DEBUG_POINTER(_Ptr);
1860  #endif /* _HAS_ITERATOR_DEBUGGING */
1861
1862         if (0 < _Count && _Off < _Mysize)
1863             {    // room for match, look for it
1864             const _Elem *const _Vptr = _Myptr() + _Mysize;
1865             for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr)
1866                 if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
1867                     return (_Uptr - _Myptr());    // found a match
1868             }
1869
1870         return (npos);    // no match
1871         }
1872
1873     size_type __CLR_OR_THIS_CALL find_first_of(const _Elem *_Ptr, size_type _Off = 0) const
1874         {    // look for one of [_Ptr, <null>) at or after _Off
1875         _DEBUG_POINTER(_Ptr);
1876         return (find_first_of(_Ptr, _Off, _Traits::length(_Ptr)));
1877         }
1878
1879     size_type __CLR_OR_THIS_CALL find_first_of(_Elem _Ch, size_type _Off = 0) const
1880         {    // look for _Ch at or after _Off
1881         return (find((const _Elem *)&_Ch, _Off, 1));
1882         }
1883
1884     size_type __CLR_OR_THIS_CALL find_last_of(const _Myt& _Right,
1885         size_type _Off = npos) const
1886         {    // look for one of _Right before _Off
1887         return (find_last_of(_Right._Myptr(), _Off, _Right.size()));
1888         }
1889
1890     size_type __CLR_OR_THIS_CALL find_last_of(const _Elem *_Ptr,
1891         size_type _Off, size_type _Count) const
1892         {    // look for one of [_Ptr, _Ptr + _Count) before _Off
1893
1894  #if _HAS_ITERATOR_DEBUGGING
1895         if (_Count != 0)
1896             _DEBUG_POINTER(_Ptr);
1897  #endif /* _HAS_ITERATOR_DEBUGGING */
1898
1899         if (0 < _Count && 0 < _Mysize)
1900             for (const _Elem *_Uptr = _Myptr()
1901                 + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr)
1902                 if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
1903                     return (_Uptr - _Myptr());    // found a match
1904                 else if (_Uptr == _Myptr())
1905                     break;    // at beginning, no more chance for match
1906
1907         return (npos);    // no match
1908         }
1909
1910     size_type __CLR_OR_THIS_CALL find_last_of(const _Elem *_Ptr,
1911         size_type _Off = npos) const
1912         {    // look for one of [_Ptr, <null>) before _Off
1913         _DEBUG_POINTER(_Ptr);
1914         return (find_last_of(_Ptr, _Off, _Traits::length(_Ptr)));
1915         }
1916
1917     size_type __CLR_OR_THIS_CALL find_last_of(_Elem _Ch, size_type _Off = npos) const
1918         {    // look for _Ch before _Off
1919         return (rfind((const _Elem *)&_Ch, _Off, 1));
1920         }
1921
1922     size_type __CLR_OR_THIS_CALL find_first_not_of(const _Myt& _Right,
1923         size_type _Off = 0) const
1924         {    // look for none of _Right at or after _Off
1925         return (find_first_not_of(_Right._Myptr(), _Off,
1926             _Right.size()));
1927         }
1928
1929     size_type __CLR_OR_THIS_CALL find_first_not_of(const _Elem *_Ptr,
1930         size_type _Off, size_type _Count) const
1931         {    // look for none of [_Ptr, _Ptr + _Count) at or after _Off
1932
1933  #if _HAS_ITERATOR_DEBUGGING
1934         if (_Count != 0)
1935             _DEBUG_POINTER(_Ptr);
1936  #endif /* _HAS_ITERATOR_DEBUGGING */
1937
1938         if (_Off < _Mysize)
1939             {    // room for match, look for it
1940             const _Elem *const _Vptr = _Myptr() + _Mysize;
1941             for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr)
1942                 if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
1943                     return (_Uptr - _Myptr());
1944             }
1945         return (npos);
1946         }
1947
1948     size_type __CLR_OR_THIS_CALL find_first_not_of(const _Elem *_Ptr,
1949         size_type _Off = 0) const
1950         {    // look for one of [_Ptr, <null>) at or after _Off
1951         _DEBUG_POINTER(_Ptr);
1952         return (find_first_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
1953         }
1954
1955     size_type __CLR_OR_THIS_CALL find_first_not_of(_Elem _Ch, size_type _Off = 0) const
1956         {    // look for non _Ch at or after _Off
1957         return (find_first_not_of((const _Elem *)&_Ch, _Off, 1));
1958         }
1959
1960     size_type __CLR_OR_THIS_CALL find_last_not_of(const _Myt& _Right,
1961         size_type _Off = npos) const
1962         {    // look for none of _Right before _Off
1963         return (find_last_not_of(_Right._Myptr(), _Off, _Right.size()));
1964         }
1965
1966     size_type __CLR_OR_THIS_CALL find_last_not_of(const _Elem *_Ptr,
1967         size_type _Off, size_type _Count) const
1968         {    // look for none of [_Ptr, _Ptr + _Count) before _Off
1969
1970  #if _HAS_ITERATOR_DEBUGGING
1971         if (_Count != 0)
1972             _DEBUG_POINTER(_Ptr);
1973  #endif /* _HAS_ITERATOR_DEBUGGING */
1974
1975         if (0 < _Mysize)
1976             for (const _Elem *_Uptr = _Myptr()
1977                 + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr)
1978                 if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
1979                     return (_Uptr - _Myptr());
1980                 else if (_Uptr == _Myptr())
1981                     break;
1982         return (npos);
1983         }
1984
1985     size_type __CLR_OR_THIS_CALL find_last_not_of(const _Elem *_Ptr,
1986         size_type _Off = npos) const
1987         {    // look for none of [_Ptr, <null>) before _Off
1988         _DEBUG_POINTER(_Ptr);
1989         return (find_last_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
1990         }
1991
1992     size_type __CLR_OR_THIS_CALL find_last_not_of(_Elem _Ch, size_type _Off = npos) const
1993         {    // look for non _Ch before _Off
1994         return (find_last_not_of((const _Elem *)&_Ch, _Off, 1));
1995         }
1996
1997     _Myt __CLR_OR_THIS_CALL substr(size_type _Off = 0, size_type _Count = npos) const
1998         {    // return [_Off, _Off + _Count) as new string
1999         return (_Myt(*this, _Off, _Count, get_allocator()));
2000         }
2001
2002     int __CLR_OR_THIS_CALL compare(const _Myt& _Right) const
2003         {    // compare [0, _Mysize) with _Right
2004         return (compare(0, _Mysize, _Right._Myptr(), _Right.size()));
2005         }
2006
2007     int __CLR_OR_THIS_CALL compare(size_type _Off, size_type _N0,
2008         const _Myt& _Right) const
2009         {    // compare [_Off, _Off + _N0) with _Right
2010         return (compare(_Off, _N0, _Right, 0, npos));
2011         }
2012
2013     int __CLR_OR_THIS_CALL compare(size_type _Off,
2014         size_type _N0, const _Myt& _Right,
2015         size_type _Roff, size_type _Count) const
2016         {    // compare [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
2017         if (_Right.size() < _Roff)
2018             _String_base::_Xran();    // _Off off end
2019         if (_Right._Mysize - _Roff < _Count)
2020             _Count = _Right._Mysize - _Roff;    // trim _Count to size
2021         return (compare(_Off, _N0, _Right._Myptr() + _Roff, _Count));
2022         }
2023
2024     int __CLR_OR_THIS_CALL compare(const _Elem *_Ptr) const
2025         {    // compare [0, _Mysize) with [_Ptr, <null>)
2026         _DEBUG_POINTER(_Ptr);
2027         return (compare(0, _Mysize, _Ptr, _Traits::length(_Ptr)));
2028         }
2029
2030     int __CLR_OR_THIS_CALL compare(size_type _Off, size_type _N0, const _Elem *_Ptr) const
2031         {    // compare [_Off, _Off + _N0) with [_Ptr, <null>)
2032         _DEBUG_POINTER(_Ptr);
2033         return (compare(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
2034         }
2035
2036     int __CLR_OR_THIS_CALL compare(size_type _Off,
2037         size_type _N0, const _Elem *_Ptr, size_type _Count) const
2038         {    // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
2039
2040  #if _HAS_ITERATOR_DEBUGGING
2041         if (_Count != 0)
2042             _DEBUG_POINTER(_Ptr);
2043  #endif /* _HAS_ITERATOR_DEBUGGING */
2044
2045         if (_Mysize < _Off)
2046             _String_base::_Xran();    // _Off off end
2047         if (_Mysize - _Off < _N0)
2048             _N0 = _Mysize - _Off;    // trim _N0 to size
2049
2050         size_type _Ans = _Traits::compare(_Myptr() + _Off, _Ptr,
2051             _N0 < _Count ? _N0 : _Count);
2052         return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1
2053             : _N0 == _Count ? 0 : +1);
2054         }
2055
2056     allocator_type __CLR_OR_THIS_CALL get_allocator() const
2057         {    // return allocator object for values
2058         return (_Mybase::_Alval);
2059         }
2060
2061     enum
2062         {    // length of internal buffer, [1, 16]
2063         _BUF_SIZE = 16 / sizeof (_Elem) < 1 ? 1
2064             : 16 / sizeof(_Elem)};
2065
2066 protected:
2067     enum
2068         {    // roundup mask for allocated buffers, [0, 15]
2069         _ALLOC_MASK = sizeof (_Elem) <= 1 ? 15
2070             : sizeof (_Elem) <= 2 ? 7
2071             : sizeof (_Elem) <= 4 ? 3
2072             : sizeof (_Elem) <= 8 ? 1 : 0};
2073
2074     void __CLR_OR_THIS_CALL _Chassign(size_type _Off, size_type _Count, _Elem _Ch)
2075         {    // assign _Count copies of _Ch beginning at _Off
2076         if (_Count == 1)
2077             _Traits::assign(*(_Myptr() + _Off), _Ch);
2078         else
2079             _Traits::assign(_Myptr() + _Off, _Count, _Ch);
2080         }
2081
2082     void __CLR_OR_THIS_CALL _Copy(size_type _Newsize, size_type _Oldlen)
2083         {    // copy _Oldlen elements to newly allocated buffer
2084         size_type _Newres = _Newsize | _ALLOC_MASK;
2085         if (max_size() < _Newres)
2086             _Newres = _Newsize;    // undo roundup if too big
2087         else if (_Newres / 3 < _Myres / 2
2088             && _Myres <= max_size() - _Myres / 2)
2089             _Newres = _Myres + _Myres / 2;    // grow exponentially if possible
2090         _Elem *_Ptr = 0;
2091
2092         _TRY_BEGIN
2093             _Ptr = _Mybase::_Alval.allocate(_Newres + 1);
2094         _CATCH_ALL
2095             _Newres = _Newsize;    // allocation failed, undo roundup and retry
2096             _TRY_BEGIN
2097                 _Ptr = _Mybase::_Alval.allocate(_Newres + 1);
2098             _CATCH_ALL
2099             _Tidy(true);    // failed again, discard storage and reraise
2100             _RERAISE;
2101             _CATCH_END
2102         _CATCH_END
2103
2104         if (0 < _Oldlen)
2105             _Traits_helper::copy_s<_Traits>(_Ptr, _Newres + 1, _Myptr(), _Oldlen);    // copy existing elements
2106         _Tidy(true);
2107         _Bx._Ptr = _Ptr;
2108         _Myres = _Newres;
2109         _Eos(_Oldlen);
2110         }
2111
2112     void __CLR_OR_THIS_CALL _Eos(size_type _Newsize)
2113         {    // set new length and null terminator
2114         _Traits::assign(_Myptr()[_Mysize = _Newsize], _Elem());
2115         }
2116
2117     bool __CLR_OR_THIS_CALL _Grow(size_type _Newsize,
2118         bool _Trim = false)
2119         {    // ensure buffer is big enough, trim to size if _Trim is true
2120             if (max_size() < _Newsize)
2121             _String_base::_Xlen();    // result too long
2122         if (_Myres < _Newsize)
2123             _Copy(_Newsize, _Mysize);    // reallocate to grow
2124         else if (_Trim && _Newsize < _BUF_SIZE)
2125             _Tidy(true,    // copy and deallocate if trimming to small string
2126                 _Newsize < _Mysize ? _Newsize : _Mysize);
2127         else if (_Newsize == 0)
2128             _Eos(0);    // new size is zero, just null terminate
2129         return (0 < _Newsize);    // return true only if more work to do
2130         }
2131
2132     bool __CLR_OR_THIS_CALL _Inside(const _Elem *_Ptr)
2133         {    // test if _Ptr points inside string
2134         if (_Ptr == 0 || _Ptr < _Myptr() || _Myptr() + _Mysize <= _Ptr)
2135             return (false);    // don't ask
2136         else
2137             return (true);
2138         }
2139
2140     static size_type __CLRCALL_OR_CDECL _Pdif(const_iterator _P2,
2141         const_iterator _P1)
2142         {    // compute safe iterator difference
2143         return (_STR_ITER_BASE(_P2) == 0 ? 0 : _P2 - _P1);
2144         }
2145
2146     void __CLR_OR_THIS_CALL _Tidy(bool _Built = false,
2147         size_type _Newsize = 0)
2148         {    // initialize buffer, deallocating any storage
2149         if (!_Built)
2150             ;
2151         else if (_BUF_SIZE <= _Myres)
2152             {    // copy any leftovers to small buffer and deallocate
2153             _Elem *_Ptr = _Bx._Ptr;
2154             if (0 < _Newsize)
2155                 _Traits_helper::copy_s<_Traits>(_Bx._Buf, _BUF_SIZE, _Ptr, _Newsize);
2156             _Mybase::_Alval.deallocate(_Ptr, _Myres + 1);
2157             }
2158         _Myres = _BUF_SIZE - 1;
2159         _Eos(_Newsize);
2160         }
2161
2162     union _Bxty
2163         {    // storage for small buffer or pointer to larger one
2164         _Elem _Buf[_BUF_SIZE];
2165         _Elem *_Ptr;
2166         } _Bx;
2167
2168     _Elem *__CLR_OR_THIS_CALL _Myptr()
2169         {    // determine current pointer to buffer for mutable string
2170         return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
2171         }
2172
2173     const _Elem *__CLR_OR_THIS_CALL _Myptr() const
2174         {    // determine current pointer to buffer for nonmutable string
2175         return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
2176         }
2177
2178     size_type _Mysize;    // current length of string
2179     size_type _Myres;    // current storage reserved for string
2180     };
2181
2182     // basic_string implements a performant swap
2183 template<class _Elem, class _Traits, class _Ax>
2184     class _Move_operation_category<basic_string<_Elem, _Traits, _Ax> >
2185     {
2186     public:
2187         typedef _Swap_move_tag _Move_cat;
2188     };
2189
2190         // STATIC npos OBJECT
2191 template<class _Elem,
2192     class _Traits,
2193     class _Alloc>
2194     _PGLOBAL const typename basic_string<_Elem, _Traits, _Alloc>::size_type
2195         basic_string<_Elem, _Traits, _Alloc>::npos =
2196             (typename basic_string<_Elem, _Traits, _Alloc>::size_type)(-1);
2197
2198         // basic_string TEMPLATE OPERATORS
2199
2200 template<class _Elem,
2201     class _Traits,
2202     class _Alloc> inline
2203     void __CLRCALL_OR_CDECL swap(basic_string<_Elem, _Traits, _Alloc>& _Left,
2204         basic_string<_Elem, _Traits, _Alloc>& _Right)
2205     {    // swap _Left and _Right strings
2206     _Left.swap(_Right);
2207     }
2208
2209 typedef basic_string<char, char_traits<char>, allocator<char> >
2210     string;
2211 typedef basic_string<wchar_t, char_traits<wchar_t>,
2212     allocator<wchar_t> > wstring;
2213
2214  #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
2215
2216 template class _CRTIMP2_PURE allocator<char>;
2217 template class _CRTIMP2_PURE allocator<wchar_t>;
2218 template class _CRTIMP2_PURE _String_val<char, allocator<char> >;
2219 template class _CRTIMP2_PURE _String_val<wchar_t, allocator<wchar_t> >;
2220 template class _CRTIMP2_PURE basic_string<char, char_traits<char>,
2221     allocator<char> >;
2222 template class _CRTIMP2_PURE basic_string<wchar_t, char_traits<wchar_t>,
2223     allocator<wchar_t> >;
2224
2225
2226
2227
2228  #endif /* _DLL_CPPLIB */
2229 _STD_END
2230 #ifdef _MSC_VER
2231  #pragma warning(default: 4251)
2232  #pragma warning(pop)
2233  #pragma pack(pop)
2234 #endif  /* _MSC_VER */
2235
2236 #endif /* RC_INVOKED */
2237 #endif /* _XSTRING */
2238
2239 /*
2240  * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
2241  * Consult your license regarding permissions and restrictions.
2242  V5.03:0009 */
2243