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 1 : __CLR_OR_THIS_CALL _String_const_iterator(pointer _Ptr, const _Container_base_secure *_Pstring)
72 : { // construct with pointer _Ptr
73 1 : _SCL_SECURE_VALIDATE(
74 : _Pstring == NULL ||
75 : _Ptr != NULL &&
76 0 : ((_Mystring *)_Pstring)->_Myptr() <= _Ptr && _Ptr <= (((_Mystring *)_Pstring)->_Myptr() + ((_Mystring *)_Pstring)->_Mysize));
77 1 : this->_Adopt(_Pstring);
78 1 : _Myptr = _Ptr;
79 1 : }
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 0 : { // 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 0 : + ((_Mystring *)this->_Mycont)->_Mysize <= _Myptr)
111 : {
112 0 : _DEBUG_ERROR("string iterator not dereferencable");
113 0 : _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 0 : return (*_Myptr);
125 0 : }
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 0 : { // preincrement
134 0 : if (this->_Mycont != _IGNORE_MYCONT)
135 : {
136 0 : _SCL_SECURE_VALIDATE(this->_Has_container());
137 0 : _SCL_SECURE_VALIDATE_RANGE(_Myptr < (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)this->_Mycont)->_Mysize));
138 : }
139 0 : ++_Myptr;
140 0 : return (*this);
141 0 : }
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 1 : { // increment by integer
170 1 : if (this->_Mycont != _IGNORE_MYCONT)
171 : {
172 1 : _SCL_SECURE_VALIDATE(this->_Has_container());
173 1 : _SCL_SECURE_VALIDATE_RANGE(
174 : _Myptr + _Off <= (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)this->_Mycont)->_Mysize) &&
175 0 : _Myptr + _Off >= ((_Mystring *)this->_Mycont)->_Myptr());
176 : }
177 1 : _Myptr += _Off;
178 1 : return (*this);
179 1 : }
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 1 : { // return difference of iterators
200 :
201 : #if _HAS_ITERATOR_DEBUGGING
202 1 : _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 1 : return (_Myptr - _Right._Myptr);
211 1 : }
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 0 : { // test for iterator equality
220 :
221 : #if _HAS_ITERATOR_DEBUGGING
222 0 : _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 0 : return (_Myptr == _Right._Myptr);
231 0 : }
232 :
233 : bool __CLR_OR_THIS_CALL operator!=(const _Myt& _Right) const
234 0 : { // test for iterator inequality
235 0 : return (!(*this == _Right));
236 0 : }
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 1 : { // test for compatible iterator pair
271 1 : if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)
272 : {
273 0 : _DEBUG_ERROR("string iterators incompatible");
274 0 : _SCL_SECURE_INVALID_ARGUMENT;
275 : }
276 1 : }
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 1 : { // construct with pointer _Ptr
335 1 : }
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 1 : { // increment by integer
405 1 : (*(_Mybase *)this) += _Off;
406 1 : return (*this);
407 1 : }
408 :
409 : _Myt __CLR_OR_THIS_CALL operator+(difference_type _Off) const
410 1 : { // return this + integer
411 1 : _Myt _Tmp = *this;
412 1 : return (_Tmp += _Off);
413 1 : }
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 20 : { // construct allocator from _Al
473 20 : }
474 :
475 : public:
476 : __CLR_OR_THIS_CALL _String_val(const _String_val &_Right)
477 : : _Alval(_Right._Alval)
478 12 : { // copy constructor
479 : #if defined(_DEBUG)
480 12 : if (_Right._Myfirstiter == _IGNORE_MYITERLIST)
481 : {
482 0 : this->_Myfirstiter = _IGNORE_MYITERLIST;
483 : }
484 : #endif
485 12 : }
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 12 : { // construct empty string
566 12 : _Tidy();
567 12 : }
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 3 : { // construct from _Right [_Roff, _Roff + _Count) with allocator
625 : #if _HAS_ITERATOR_DEBUGGING
626 3 : if (_Right._Myfirstiter == _IGNORE_MYITERLIST)
627 : {
628 0 : this->_Myfirstiter = _IGNORE_MYITERLIST;
629 : }
630 : #endif
631 3 : _Tidy();
632 3 : assign(_Right, _Roff, _Count);
633 3 : }
634 :
635 : __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr, size_type _Count)
636 : : _Mybase()
637 10 : { // construct from [_Ptr, _Ptr + _Count)
638 10 : _Tidy();
639 10 : assign(_Ptr, _Count);
640 10 : }
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 12 : { // construct from [_Ptr, <null>)
652 12 : _Tidy();
653 12 : assign(_Ptr);
654 12 : }
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 7 : { // construct from [_First, _Last)
681 7 : _Tidy();
682 7 : _Construct(_First, _Last, _Iter_cat(_First));
683 7 : }
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 0 : { // construct from [_First, _Last), const pointers
696 : #if defined(_DEBUG)
697 0 : _DEBUG_RANGE(_First, _Last);
698 : #endif
699 0 : _Tidy();
700 0 : if (_First != _Last)
701 0 : assign(&*_First, _Last - _First);
702 0 : }
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 12 : { // construct by copying _Right
722 12 : _Tidy();
723 12 : assign(_Right, 0, npos);
724 12 : }
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 7 : 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 7 : if (this->_Myfirstiter != _IGNORE_MYITERLIST)
887 : {
888 7 : _DEBUG_RANGE(_First, _Last);
889 : }
890 : #endif
891 7 : size_type _Count = 0;
892 7 : _Distance(_First, _Last, _Count);
893 7 : reserve(_Count);
894 :
895 7 : _TRY_BEGIN
896 7 : for (; _First != _Last; ++_First)
897 7 : append((size_type)1, (_Elem)*_First);
898 : _CATCH_ALL
899 0 : _Tidy(true);
900 0 : _RERAISE;
901 0 : _CATCH_END
902 7 : }
903 :
904 : __CLR_OR_THIS_CALL ~basic_string()
905 20 : { // destroy the string
906 20 : _Tidy(true);
907 20 : }
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 9 : { // assign _Right
916 9 : return (assign(_Right));
917 9 : }
918 :
919 : _Myt& __CLR_OR_THIS_CALL operator=(const _Elem *_Ptr)
920 11 : { // assign [_Ptr, <null>)
921 11 : return (assign(_Ptr));
922 11 : }
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 3 : { // append _Right
931 3 : return (append(_Right));
932 3 : }
933 :
934 : _Myt& __CLR_OR_THIS_CALL operator+=(const _Elem *_Ptr)
935 9 : { // append [_Ptr, <null>)
936 9 : return (append(_Ptr));
937 9 : }
938 :
939 : _Myt& __CLR_OR_THIS_CALL operator+=(_Elem _Ch)
940 10 : { // append 1 * _Ch
941 10 : return (append((size_type)1, _Ch));
942 10 : }
943 :
944 : _Myt& __CLR_OR_THIS_CALL append(const _Myt& _Right)
945 3 : { // append _Right
946 3 : return (append(_Right, 0, npos));
947 3 : }
948 :
949 : _Myt& __CLR_OR_THIS_CALL append(const _Myt& _Right,
950 : size_type _Roff, size_type _Count)
951 3 : { // append _Right [_Roff, _Roff + _Count)
952 3 : if (_Right.size() < _Roff)
953 0 : _String_base::_Xran(); // _Roff off end
954 3 : size_type _Num = _Right.size() - _Roff;
955 3 : if (_Num < _Count)
956 3 : _Count = _Num; // trim _Count to size
957 3 : if (npos - _Mysize <= _Count || _Mysize + _Count < _Mysize)
958 0 : _String_base::_Xlen(); // result too long
959 :
960 3 : 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 3 : _Right._Myptr() + _Roff, _Count);
964 3 : _Eos(_Num);
965 : }
966 3 : return (*this);
967 3 : }
968 :
969 : _Myt& __CLR_OR_THIS_CALL append(const _Elem *_Ptr, size_type _Count)
970 9 : { // append [_Ptr, _Ptr + _Count)
971 :
972 : #if _HAS_ITERATOR_DEBUGGING
973 9 : if (_Count != 0)
974 9 : _DEBUG_POINTER(_Ptr);
975 : #endif /* _HAS_ITERATOR_DEBUGGING */
976 :
977 9 : if (_Inside(_Ptr))
978 0 : return (append(*this, _Ptr - _Myptr(), _Count)); // substring
979 9 : if (npos - _Mysize <= _Count || _Mysize + _Count < _Mysize)
980 0 : _String_base::_Xlen(); // result too long
981 :
982 : size_type _Num;
983 9 : if (0 < _Count && _Grow(_Num = _Mysize + _Count))
984 : { // make room and append new stuff
985 9 : _Traits_helper::copy_s<_Traits>(_Myptr() + _Mysize, _Myres - _Mysize, _Ptr, _Count);
986 9 : _Eos(_Num);
987 : }
988 9 : return (*this);
989 9 : }
990 :
991 : _Myt& __CLR_OR_THIS_CALL append(const _Elem *_Ptr)
992 9 : { // append [_Ptr, <null>)
993 9 : _DEBUG_POINTER(_Ptr);
994 9 : return (append(_Ptr, _Traits::length(_Ptr)));
995 9 : }
996 :
997 : _Myt& __CLR_OR_THIS_CALL append(size_type _Count, _Elem _Ch)
998 17 : { // append _Count * _Ch
999 17 : if (npos - _Mysize <= _Count)
1000 0 : _String_base::_Xlen(); // result too long
1001 :
1002 : size_type _Num;
1003 17 : if (0 < _Count && _Grow(_Num = _Mysize + _Count))
1004 : { // make room and append new stuff using assign
1005 17 : _Chassign(_Mysize, _Count, _Ch);
1006 17 : _Eos(_Num);
1007 : }
1008 17 : return (*this);
1009 17 : }
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 9 : { // assign _Right
1041 9 : return (assign(_Right, 0, npos));
1042 9 : }
1043 :
1044 : _Myt& __CLR_OR_THIS_CALL assign(const _Myt& _Right,
1045 : size_type _Roff, size_type _Count)
1046 12 : { // assign _Right [_Roff, _Roff + _Count)
1047 12 : if (_Right.size() < _Roff)
1048 0 : _String_base::_Xran(); // _Roff off end
1049 12 : size_type _Num = _Right.size() - _Roff;
1050 12 : if (_Count < _Num)
1051 3 : _Num = _Count; // trim _Num to size
1052 :
1053 12 : if (this == &_Right)
1054 0 : erase((size_type)(_Roff + _Num)), erase(0, _Roff); // substring
1055 12 : else if (_Grow(_Num))
1056 : { // make room and assign new stuff
1057 12 : _Traits_helper::copy_s<_Traits>(_Myptr(), _Myres, _Right._Myptr() + _Roff, _Num);
1058 12 : _Eos(_Num);
1059 : }
1060 12 : return (*this);
1061 12 : }
1062 :
1063 : _Myt& __CLR_OR_THIS_CALL assign(const _Elem *_Ptr, size_type _Count)
1064 13 : { // assign [_Ptr, _Ptr + _Count)
1065 :
1066 : #if _HAS_ITERATOR_DEBUGGING
1067 13 : if (_Count != 0)
1068 13 : _DEBUG_POINTER(_Ptr);
1069 : #endif /* _HAS_ITERATOR_DEBUGGING */
1070 :
1071 13 : if (_Inside(_Ptr))
1072 0 : return (assign(*this, _Ptr - _Myptr(), _Count)); // substring
1073 :
1074 13 : if (_Grow(_Count))
1075 : { // make room and assign new stuff
1076 13 : _Traits_helper::copy_s<_Traits>(_Myptr(), _Myres, _Ptr, _Count);
1077 13 : _Eos(_Count);
1078 : }
1079 13 : return (*this);
1080 13 : }
1081 :
1082 : _Myt& __CLR_OR_THIS_CALL assign(const _Elem *_Ptr)
1083 13 : { // assign [_Ptr, <null>)
1084 13 : _DEBUG_POINTER(_Ptr);
1085 13 : return (assign(_Ptr, _Traits::length(_Ptr)));
1086 13 : }
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 1 : { // insert _Count * _Ch at _Off
1197 1 : if (_Mysize < _Off)
1198 0 : _String_base::_Xran(); // _Off off end
1199 1 : if (npos - _Mysize <= _Count)
1200 0 : _String_base::_Xlen(); // result too long
1201 : size_type _Num;
1202 1 : 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 1 : _Myptr() + _Off, _Mysize - _Off); // empty out hole
1206 1 : _Chassign(_Off, _Count, _Ch); // fill hole
1207 1 : _Eos(_Num);
1208 : }
1209 1 : return (*this);
1210 1 : }
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 1 : { // insert _Ch at _Where
1219 1 : size_type _Off = _Pdif(_Where, begin());
1220 1 : insert(_Off, 1, _Ch);
1221 1 : return (begin() + _Off);
1222 1 : }
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 :
1260 : _Myt& __CLR_OR_THIS_CALL erase(size_type _Off = 0,
1261 : size_type _Count = npos)
1262 0 : { // erase elements [_Off, _Off + _Count)
1263 0 : if (_Mysize < _Off)
1264 0 : _String_base::_Xran(); // _Off off end
1265 0 : if (_Mysize - _Off < _Count)
1266 0 : _Count = _Mysize - _Off; // trim _Count
1267 0 : if (0 < _Count)
1268 : { // move elements down
1269 : _Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off, _Myptr() + _Off + _Count,
1270 0 : _Mysize - _Off - _Count);
1271 0 : size_type _Newsize = _Mysize - _Count;
1272 0 : _Eos(_Newsize);
1273 : }
1274 0 : return (*this);
1275 0 : }
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 0 : { // erase substring [_First, _Last)
1286 0 : size_type _Count = _Pdif(_First, begin());
1287 0 : erase(_Count, _Pdif(_Last, _First));
1288 0 : return (_STRING_ITERATOR(_Myptr() + _Count));
1289 0 : }
1290 :
1291 : void __CLR_OR_THIS_CALL clear()
1292 0 : { // erase all
1293 0 : erase(begin(), end());
1294 0 : }
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 1 : { // return iterator for beginning of mutable sequence
1502 1 : return (_STRING_ITERATOR(_Myptr()));
1503 1 : }
1504 :
1505 : const_iterator __CLR_OR_THIS_CALL begin() const
1506 0 : { // return iterator for beginning of nonmutable sequence
1507 0 : return (_STRING_CONST_ITERATOR(_Myptr()));
1508 0 : }
1509 :
1510 : iterator __CLR_OR_THIS_CALL end()
1511 1 : { // return iterator for end of mutable sequence
1512 1 : return (_STRING_ITERATOR(_Myptr() + _Mysize));
1513 1 : }
1514 :
1515 : const_iterator __CLR_OR_THIS_CALL end() const
1516 0 : { // return iterator for end of nonmutable sequence
1517 0 : return (_STRING_CONST_ITERATOR(_Myptr() + _Mysize));
1518 0 : }
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 1 : { // subscript mutable sequence
1558 :
1559 : #if _HAS_ITERATOR_DEBUGGING
1560 : // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1561 1 : if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1562 : {
1563 1 : if (_Mysize < _Off)
1564 : {
1565 0 : _DEBUG_ERROR("string subscript out of range");
1566 0 : _SCL_SECURE_OUT_OF_RANGE;
1567 : }
1568 : }
1569 : #else
1570 : _SCL_SECURE_VALIDATE_RANGE(_Off <= _Mysize);
1571 : #endif /* _HAS_ITERATOR_DEBUGGING */
1572 :
1573 1 : return (_Myptr()[_Off]);
1574 1 : }
1575 :
1576 : const_reference __CLR_OR_THIS_CALL operator[](size_type _Off) const
1577 3 : { // subscript nonmutable sequence
1578 :
1579 : #if _HAS_ITERATOR_DEBUGGING
1580 : // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST
1581 3 : if (this->_Myfirstiter != _IGNORE_MYITERLIST)
1582 : {
1583 3 : if (_Mysize < _Off) // sic
1584 : {
1585 0 : _DEBUG_ERROR("string subscript out of range");
1586 0 : _SCL_SECURE_OUT_OF_RANGE;
1587 : }
1588 : }
1589 : #else
1590 : _SCL_SECURE_VALIDATE_RANGE(_Off <= _Mysize);
1591 : #endif /* _HAS_ITERATOR_DEBUGGING */
1592 :
1593 3 : return (_Myptr()[_Off]);
1594 3 : }
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 1 : { // insert element at end
1646 1 : insert(end(), _Ch);
1647 1 : }
1648 :
1649 : const _Elem *__CLR_OR_THIS_CALL c_str() const
1650 28 : { // return pointer to null-terminated nonmutable array
1651 28 : return (_Myptr());
1652 28 : }
1653 :
1654 : const _Elem *__CLR_OR_THIS_CALL data() const
1655 1 : { // return pointer to nonmutable array
1656 1 : return (c_str());
1657 1 : }
1658 :
1659 : size_type __CLR_OR_THIS_CALL length() const
1660 10 : { // return length of sequence
1661 10 : return (_Mysize);
1662 10 : }
1663 :
1664 : size_type __CLR_OR_THIS_CALL size() const
1665 12 : { // return length of sequence
1666 12 : return (_Mysize);
1667 12 : }
1668 :
1669 : size_type __CLR_OR_THIS_CALL max_size() const
1670 20 : { // return maximum possible length of sequence
1671 20 : size_type _Num = _Mybase::_Alval.max_size();
1672 20 : return (_Num <= 1 ? 1 : _Num - 1);
1673 20 : }
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 16 : { // determine new minimum length of allocated storage
1695 16 : if (_Mysize <= _Newcap && _Myres != _Newcap)
1696 : { // change reservation
1697 16 : size_type _Size = _Mysize;
1698 16 : if (_Grow(_Newcap, true))
1699 16 : _Eos(_Size);
1700 : }
1701 16 : }
1702 :
1703 : bool __CLR_OR_THIS_CALL empty() const
1704 9 : { // test if sequence is empty
1705 9 : return (_Mysize == 0);
1706 9 : }
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 4 : { // exchange contents with _Right
1736 4 : if (this == &_Right)
1737 : ; // same object, do nothing
1738 4 : else if (_Mybase::_Alval == _Right._Alval)
1739 : { // same allocator, swap control information
1740 :
1741 : #if _HAS_ITERATOR_DEBUGGING
1742 4 : this->_Swap_all(_Right);
1743 : #endif /* _HAS_ITERATOR_DEBUGGING */
1744 :
1745 4 : _Bxty _Tbx = _Bx;
1746 4 : _Bx = _Right._Bx, _Right._Bx = _Tbx;
1747 :
1748 4 : size_type _Tlen = _Mysize;
1749 4 : _Mysize = _Right._Mysize, _Right._Mysize = _Tlen;
1750 :
1751 4 : size_type _Tres = _Myres;
1752 4 : _Myres = _Right._Myres, _Right._Myres = _Tres;
1753 : }
1754 4 : else
1755 : { // different allocator, do multiple assigns
1756 0 : _Myt _Tmp = *this;
1757 :
1758 0 : *this = _Right;
1759 0 : _Right = _Tmp;
1760 0 : }
1761 4 : }
1762 :
1763 : size_type __CLR_OR_THIS_CALL find(const _Myt& _Right, size_type _Off = 0) const
1764 0 : { // look for _Right beginnng at or after _Off
1765 0 : return (find(_Right._Myptr(), _Off, _Right.size()));
1766 0 : }
1767 :
1768 : size_type __CLR_OR_THIS_CALL find(const _Elem *_Ptr,
1769 : size_type _Off, size_type _Count) const
1770 0 : { // look for [_Ptr, _Ptr + _Count) beginnng at or after _Off
1771 :
1772 : #if _HAS_ITERATOR_DEBUGGING
1773 0 : if (_Count != 0)
1774 0 : _DEBUG_POINTER(_Ptr);
1775 : #endif /* _HAS_ITERATOR_DEBUGGING */
1776 :
1777 0 : if (_Count == 0 && _Off <= _Mysize)
1778 0 : return (_Off); // null string always matches (if inside string)
1779 :
1780 : size_type _Nm;
1781 0 : if (_Off < _Mysize && _Count <= (_Nm = _Mysize - _Off))
1782 : { // room for match, look for it
1783 : const _Elem *_Uptr, *_Vptr;
1784 0 : for (_Nm -= _Count - 1, _Vptr = _Myptr() + _Off;
1785 : (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0;
1786 0 : _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1)
1787 0 : if (_Traits::compare(_Uptr, _Ptr, _Count) == 0)
1788 0 : return (_Uptr - _Myptr()); // found a match
1789 0 : }
1790 :
1791 0 : return (npos); // no match
1792 0 : }
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 0 : { // look for _Ch at or after _Off
1802 0 : return (find((const _Elem *)&_Ch, _Off, 1));
1803 0 : }
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 3 : { // return [_Off, _Off + _Count) as new string
1999 3 : return (_Myt(*this, _Off, _Count, get_allocator()));
2000 3 : }
2001 :
2002 : int __CLR_OR_THIS_CALL compare(const _Myt& _Right) const
2003 2 : { // compare [0, _Mysize) with _Right
2004 2 : return (compare(0, _Mysize, _Right._Myptr(), _Right.size()));
2005 2 : }
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 11 : { // compare [0, _Mysize) with [_Ptr, <null>)
2026 11 : _DEBUG_POINTER(_Ptr);
2027 11 : return (compare(0, _Mysize, _Ptr, _Traits::length(_Ptr)));
2028 11 : }
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 11 : { // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
2039 :
2040 : #if _HAS_ITERATOR_DEBUGGING
2041 11 : if (_Count != 0)
2042 11 : _DEBUG_POINTER(_Ptr);
2043 : #endif /* _HAS_ITERATOR_DEBUGGING */
2044 :
2045 11 : if (_Mysize < _Off)
2046 0 : _String_base::_Xran(); // _Off off end
2047 11 : if (_Mysize - _Off < _N0)
2048 0 : _N0 = _Mysize - _Off; // trim _N0 to size
2049 :
2050 : size_type _Ans = _Traits::compare(_Myptr() + _Off, _Ptr,
2051 11 : _N0 < _Count ? _N0 : _Count);
2052 : return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1
2053 11 : : _N0 == _Count ? 0 : +1);
2054 11 : }
2055 :
2056 : allocator_type __CLR_OR_THIS_CALL get_allocator() const
2057 3 : { // return allocator object for values
2058 3 : return (_Mybase::_Alval);
2059 3 : }
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 18 : { // assign _Count copies of _Ch beginning at _Off
2076 18 : if (_Count == 1)
2077 18 : _Traits::assign(*(_Myptr() + _Off), _Ch);
2078 18 : else
2079 0 : _Traits::assign(_Myptr() + _Off, _Count, _Ch);
2080 18 : }
2081 :
2082 : void __CLR_OR_THIS_CALL _Copy(size_type _Newsize, size_type _Oldlen)
2083 19 : { // copy _Oldlen elements to newly allocated buffer
2084 19 : size_type _Newres = _Newsize | _ALLOC_MASK;
2085 19 : if (max_size() < _Newres)
2086 0 : _Newres = _Newsize; // undo roundup if too big
2087 0 : else if (_Newres / 3 < _Myres / 2
2088 19 : && _Myres <= max_size() - _Myres / 2)
2089 2 : _Newres = _Myres + _Myres / 2; // grow exponentially if possible
2090 19 : _Elem *_Ptr = 0;
2091 :
2092 19 : _TRY_BEGIN
2093 19 : _Ptr = _Mybase::_Alval.allocate(_Newres + 1);
2094 0 : _CATCH_ALL
2095 0 : _Newres = _Newsize; // allocation failed, undo roundup and retry
2096 0 : _TRY_BEGIN
2097 0 : _Ptr = _Mybase::_Alval.allocate(_Newres + 1);
2098 : _CATCH_ALL
2099 0 : _Tidy(true); // failed again, discard storage and reraise
2100 0 : _RERAISE;
2101 0 : _CATCH_END
2102 0 : _CATCH_END
2103 :
2104 19 : if (0 < _Oldlen)
2105 11 : _Traits_helper::copy_s<_Traits>(_Ptr, _Newres + 1, _Myptr(), _Oldlen); // copy existing elements
2106 19 : _Tidy(true);
2107 19 : _Bx._Ptr = _Ptr;
2108 19 : _Myres = _Newres;
2109 19 : _Eos(_Oldlen);
2110 19 : }
2111 :
2112 : void __CLR_OR_THIS_CALL _Eos(size_type _Newsize)
2113 20 : { // set new length and null terminator
2114 20 : _Traits::assign(_Myptr()[_Mysize = _Newsize], _Elem());
2115 20 : }
2116 :
2117 : bool __CLR_OR_THIS_CALL _Grow(size_type _Newsize,
2118 : bool _Trim = false)
2119 20 : { // ensure buffer is big enough, trim to size if _Trim is true
2120 20 : if (max_size() < _Newsize)
2121 0 : _String_base::_Xlen(); // result too long
2122 20 : if (_Myres < _Newsize)
2123 19 : _Copy(_Newsize, _Mysize); // reallocate to grow
2124 20 : else if (_Trim && _Newsize < _BUF_SIZE)
2125 : _Tidy(true, // copy and deallocate if trimming to small string
2126 9 : _Newsize < _Mysize ? _Newsize : _Mysize);
2127 20 : else if (_Newsize == 0)
2128 10 : _Eos(0); // new size is zero, just null terminate
2129 20 : return (0 < _Newsize); // return true only if more work to do
2130 20 : }
2131 :
2132 : bool __CLR_OR_THIS_CALL _Inside(const _Elem *_Ptr)
2133 13 : { // test if _Ptr points inside string
2134 13 : if (_Ptr == 0 || _Ptr < _Myptr() || _Myptr() + _Mysize <= _Ptr)
2135 13 : return (false); // don't ask
2136 : else
2137 0 : return (true);
2138 13 : }
2139 :
2140 : static size_type __CLRCALL_OR_CDECL _Pdif(const_iterator _P2,
2141 : const_iterator _P1)
2142 1 : { // compute safe iterator difference
2143 1 : return (_STR_ITER_BASE(_P2) == 0 ? 0 : _P2 - _P1);
2144 1 : }
2145 :
2146 : void __CLR_OR_THIS_CALL _Tidy(bool _Built = false,
2147 : size_type _Newsize = 0)
2148 20 : { // initialize buffer, deallocating any storage
2149 20 : if (!_Built)
2150 : ;
2151 20 : else if (_BUF_SIZE <= _Myres)
2152 : { // copy any leftovers to small buffer and deallocate
2153 19 : _Elem *_Ptr = _Bx._Ptr;
2154 19 : if (0 < _Newsize)
2155 0 : _Traits_helper::copy_s<_Traits>(_Bx._Buf, _BUF_SIZE, _Ptr, _Newsize);
2156 19 : _Mybase::_Alval.deallocate(_Ptr, _Myres + 1);
2157 : }
2158 20 : _Myres = _BUF_SIZE - 1;
2159 20 : _Eos(_Newsize);
2160 20 : }
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 20 : { // determine current pointer to buffer for mutable string
2170 20 : return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
2171 20 : }
2172 :
2173 : const _Elem *__CLR_OR_THIS_CALL _Myptr() const
2174 29 : { // determine current pointer to buffer for nonmutable string
2175 29 : return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
2176 29 : }
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 4 : { // swap _Left and _Right strings
2206 4 : _Left.swap(_Right);
2207 4 : }
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 */
|