Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
string.cc
Go to the documentation of this file.
1
29#ifdef _RWSTD_MSVC
30 // shut up the dumb MSVC warning C4345:
31 // behavior change: an object with POD type constructed with
32 // an initializer of the form () will be default-initialized
33# pragma warning (push)
34# pragma warning (disable: 4345)
35#endif // _RWSTD_MSVC
36
37
39
40
41#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_INIT
42# if !defined (_RWSTD_MSVC) || _RWSTD_MSVC > 1300
43 // MSVC 7.0 allows initializers for static const integral members
44 // but out-of-line definitions cause multiply defined symbol errors
45 // (see PR #26562)
46
47# ifndef _RWSTD_NO_STRING_NPOS_TYPE
48
49template <class _CharT, class _Traits, class _Allocator>
50const typename basic_string<_CharT, _Traits, _Allocator>::size_type
51basic_string<_CharT, _Traits, _Allocator>::
52npos /* = SIZE_MAX */;
53
54# else // if defined (_RWSTD_NO_STRING_NPOS_TYPE)
55
56template <class _CharT, class _Traits, class _Allocator>
57const _RWSTD_SIZE_T
58basic_string<_CharT, _Traits, _Allocator>::
59npos /* = SIZE_MAX */;
60
61# endif // _RWSTD_NO_STRING_NPOS_TYPE
62# endif // MSVC > 7.0
63#endif // _RWSTD_NO_STATIC_CONST_MEMBER_INIT
64
65
66#ifndef _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
67
68template <class _CharT, class _Traits, class _Allocator>
69_RW::__null_ref<_CharT, _Traits, _Allocator>
70basic_string<_CharT, _Traits, _Allocator>::
71_C_null_ref;
72
73#endif // _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
74
75
76template <class _CharT, class _Traits, class _Allocator>
77typename basic_string<_CharT, _Traits, _Allocator>::_C_string_ref_type*
78basic_string<_CharT, _Traits, _Allocator>::
79_C_get_rep (size_type __cap, size_type __len)
80{
81 if (__cap > max_size ()) {
82 __cap = __len;
83
84 _RWSTD_REQUIRES (__cap <= max_size (),
86 _RWSTD_FUNC ("basic_string::_C_get_rep (size_type, "
87 "size_type)"),
88 __cap, max_size ()));
89 }
90
91 _RWSTD_REQUIRES (__len <= __cap,
93 _RWSTD_FUNC ("basic_string::_C_get_rep (size_type, "
94 "size_type)"),
95 __len, __cap));
96
97 if (!__cap) {
98 _RWSTD_ASSERT (!__len);
99 return _C_nullref ();
100 }
101
102 // allocate, initialize the __string_ref, and initialize each character
103 _C_string_ref_type* const __ret =
104 _RWSTD_STATIC_CAST (_C_string_ref_type*,
105 _RWSTD_STATIC_CAST (void*,
106 _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
107 allocate ( __cap + sizeof (_C_string_ref_type)
108 / sizeof (value_type) + 2))));
109
110 // avoid copy construction (mutex isn't copy-constructible)
111 // _C_ref_alloc_type (*this).construct (__ret, _C_string_ref_type ());
112 new (__ret) _C_string_ref_type ();
113
114 // set initial reference count, capacity, and length
115 __ret->_C_init (__cap, __len);
116
117 _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
118 construct (__ret->data () + __len, value_type ()));
119
120 return __ret;
121}
122
123
124template <class _CharT, class _Traits, class _Allocator>
125basic_string<_CharT, _Traits, _Allocator>::
126basic_string (const basic_string &__s, size_type __pos, size_type __n,
127 const allocator_type& __alloc /* = allocator_type () */)
128 : allocator_type (__alloc)
129{
130 _RWSTD_REQUIRES (__pos <= __s.size (),
132 _RWSTD_FUNC ("basic_string::basic_string (const "
133 "basic_string&, size_type, size_type)"),
134 __pos, __s.size ()));
135
136 size_type __slen = __s.size () - __pos;
137 size_type __rlen = __n < __slen ? __n : __slen;
138 size_type __nlen = __n == npos ? 0 : __n;
139 size_type __maxlen = __nlen > __rlen ? __nlen : __rlen;
140 if (__maxlen)
141 _C_data = _C_get_rep (_C_grow (size_type (), __maxlen),
142 __rlen)->data ();
143 else
144 _C_data = _C_get_rep (__maxlen, __rlen)->data ();
145
146 traits_type::copy (_C_data, &__s._C_data [__pos], __rlen);
147}
148
149
150template <class _CharT, class _Traits, class _Allocator>
151basic_string<_CharT, _Traits, _Allocator>::
152basic_string (size_type __n, value_type __c,
153 const allocator_type &__alloc /* = allocator_type () */)
154 : allocator_type (__alloc)
155{
156 _RWSTD_REQUIRES (__n <= max_size (),
158 _RWSTD_FUNC ("basic_string::basic_string (size_type, "
159 "value_type)"),
160 __n, max_size ()));
161
162 if (__n)
163 _C_data = _C_get_rep (_C_grow (size_type (), __n), __n)->data ();
164 else
165 _C_data = _C_nullref ()->data ();
166
167 traits_type::assign (_C_data, __n, __c);
168}
169
170
171template <class _CharT, class _Traits, class _Allocator>
172basic_string<_CharT, _Traits, _Allocator>::
173basic_string (const_pointer __s, size_type __n,
174 const allocator_type &__alloc /* = allocator_type () */)
175 : allocator_type (__alloc)
176{
177 // extension: if `s' is 0 then `n' uninitialized elements are allocated
178
179 _RWSTD_REQUIRES (__n <= max_size (),
181 _RWSTD_FUNC ("basic_string::basic_string (const_pointer,"
182 "size_type, const allocator_type&)"),
183 __n, max_size ()));
184
185 _C_data = __n ?
186 _C_get_rep (_C_grow (size_type (), __n), __n)->data ()
187 : _C_nullref ()->data ();
188
189 if (__s)
190 traits_type::copy (_C_data, __s, __n);
191}
192
193
194template <class _CharT, class _Traits, class _Allocator>
195basic_string<_CharT, _Traits, _Allocator>::
196basic_string (const_pointer __s,
197 const allocator_type &__alloc /* = allocator_type () */)
198 : allocator_type (__alloc)
199{
200 _RWSTD_ASSERT (__s != 0);
201
202 const size_type __n = traits_type::length (__s);
203
204 _C_data = __n ?
205 _C_get_rep (_C_grow (size_type (), __n), __n)->data ()
206 : _C_nullref ()->data ();
207
208 traits_type::copy (_C_data, __s, __n);
209}
210
211
212template <class _CharT, class _Traits, class _Allocator>
213basic_string<_CharT, _Traits, _Allocator>::
214basic_string (const_pointer __first, const_pointer __last,
215 const allocator_type &__alloc /* = allocator_type () */)
216 : allocator_type (__alloc)
217{
218 const size_type __n = size_type (__last - __first);
219
220 _C_data = __n ?
221 _C_get_rep (_C_grow (size_type (), __n), __n)->data ()
222 : _C_nullref ()->data ();
223
224 traits_type::copy (_C_data, __first, __n);
225}
226
227
228template <class _CharT, class _Traits, class _Allocator>
229basic_string<_CharT, _Traits, _Allocator>&
230basic_string<_CharT, _Traits, _Allocator>::
231operator= (const basic_string &__rhs)
232{
233 if (size_type (0) < size_type (__rhs._C_pref ()->_C_get_ref ())) {
234 // `rhs' has reference counting enabled
235 __rhs._C_pref ()->_C_inc_ref ();
236 _C_unlink (__rhs._C_data);
237 }
238 else if (this != &__rhs)
239 // `rhs' has reference counting disabled
240 replace (size_type (), size (), __rhs.data (), __rhs.size ());
241
242 return *this;
243}
244
245
246template <class _CharT, class _Traits, class _Allocator>
247basic_string<_CharT, _Traits, _Allocator>&
248basic_string<_CharT, _Traits, _Allocator>::
249assign (const basic_string &__str, size_type __pos, size_type __n)
250{
251 _RWSTD_REQUIRES (__pos <= __str.size (),
253 _RWSTD_FUNC ("basic_string::assign (basic_string&, "
254 "size_type, size_type)"),
255 __pos, __str.size ()));
256
257 const size_type __rlen = _C_min (__str.size () - __pos, __n);
258
259 return replace (size_type (), size (), __str, __pos, __rlen);
260}
261
262
263template <class _CharT, class _Traits, class _Allocator>
264basic_string<_CharT, _Traits, _Allocator>&
265basic_string<_CharT, _Traits, _Allocator>::
266insert (size_type __pos1,
267 const basic_string& __str, size_type __pos2, size_type __n)
268{
269 _RWSTD_REQUIRES (__pos1 <= size () && __pos2 <= __str.size (),
271 _RWSTD_FUNC ("basic_string::insert (size_type, const "
272 "basic_string&, size_type, size_type)"),
273 __pos1 > size () ? __pos1:__pos2, __str.size ()));
274
275 const size_type __rlen = _C_min (__str.size () - __pos2, __n);
276
277 _RWSTD_REQUIRES (size () <= max_size () - __rlen,
279 _RWSTD_FUNC ("basic_string::insert (size_type, const "
280 "basic_string&, size_type, size_type)"),
281 size (), max_size () - __rlen));
282
283 return replace (__pos1, size_type (), __str, __pos2, __n);
284}
285
286
287template <class _CharT, class _Traits, class _Allocator>
288basic_string<_CharT, _Traits, _Allocator>&
289basic_string<_CharT, _Traits, _Allocator>::
290insert (size_type __pos1, const basic_string &__str)
291{
292 _RWSTD_REQUIRES (__pos1 <= size (),
294 _RWSTD_FUNC ("basic_string::insert (size_type, const "
295 "basic_string&)"),
296 __pos1, size ()));
297
298 _RWSTD_REQUIRES (size () <= max_size () - __str.size (),
300 _RWSTD_FUNC ("basic_string::insert (size_type, "
301 "const basic_string&)"),
302 size (), max_size () - __str.size ()));
303
304 return replace (__pos1, size_type (), __str);
305}
306
307
308template <class _CharT, class _Traits, class _Allocator>
309basic_string<_CharT, _Traits, _Allocator>&
310basic_string<_CharT, _Traits, _Allocator>::
311replace (size_type __pos1, size_type __n1, const_pointer __s, size_type __n2)
312{
313 const size_type __size0 = size ();
314
315 if (npos == __n2)
316 __n2 = traits_type::length (__s);
317
318 _RWSTD_REQUIRES (__pos1 <= __size0,
320 _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
321 ", const_pointer, size_type)"),
322 __pos1, __size0 > __n2 ? __size0 : __n2));
323
324 // number of characters to delete
325 const size_type __xlen = _C_min (__n1, __size0 - __pos1);
326
327 _RWSTD_REQUIRES (__n2 <= max_size (),
329 _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
330 ", const_pointer, size_type)"),
331 __n2, max_size ()));
332
333 _RWSTD_REQUIRES (__size0 - __xlen <= max_size () - __n2,
335 _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
336 ", const_pointer, size_type)"),
337 __size0 - __xlen, max_size () - __n2));
338
339 // compute the resulting string size
340 const size_type __size1 = __size0 - __xlen + __n2;
341
342 if (__size1) {
343
344 // compute the length of the bit at the end
345 const size_type __rem = __size0 - __xlen - __pos1;
346
347 // check for shared representation, insufficient capacity,
348 // and overlapping regions
349 if ( size_type (1) < size_type (_C_pref ()->_C_get_ref ())
350 || capacity () < __size1
351 || __s >= data () && __s < data () + __size0) {
352
353 // Need to allocate a new reference.
354 const size_type __cap = _C_grow (__size0, __size1);
355
356 const pointer __data = _C_get_rep (__cap, __size1)->data ();
357
358 traits_type::copy (__data, _C_data, __pos1);
359
360 traits_type::copy (__data + __pos1, __s, __n2);
361
362 traits_type::copy (__data + __pos1 + __n2,
363 _C_data + __pos1 + __n1, __rem);
364
365 _C_unlink (__data);
366 }
367 else {
368 // current reference has enough space
369
370 const pointer __beg = _C_data + __pos1;
371
372 traits_type::move (__beg + __n2, __beg + __n1, __rem);
373
374 traits_type::copy (__beg, __s, __n2);
375
376 traits_type::assign (_C_data [__size1], value_type ());
377
378 _C_pref ()->_C_size._C_size = __size1;
379 }
380 }
381 else {
382 // special case a substitution that leaves the string empty.
383 clear ();
384 }
385
386 return *this;
387}
388
389
390template <class _CharT, class _Traits, class _Allocator>
391basic_string<_CharT, _Traits, _Allocator>&
392basic_string<_CharT, _Traits, _Allocator>::
393replace (size_type __pos, size_type __len, size_type __count, value_type __val)
394{
395 // replaces `len' characters at position `pos'
396 // with `count' copies of the character `val'
397
398 const size_type __size0 = size ();
399
400 _RWSTD_REQUIRES (__pos <= __size0,
402 _RWSTD_FUNC ("basic_string::replace (size_type, "
403 "size_type, size_type, value_type)"),
404 __pos, __size0));
405
406 const size_type __xlen = _C_min (__size0 - __pos, __len);
407
408 _RWSTD_REQUIRES (__size0 - __xlen <= max_size () - __count,
410 _RWSTD_FUNC ("basic_string::replace (size_type, "
411 "size_type, size_type, value_type)"),
412 __size0 - __xlen, max_size () - __count));
413
414 // compute the resulting string size
415 const size_type __size1 = __size0 - __xlen + __count;
416
417 if (__size1) {
418
419 // compute the length of the bit at the end
420 const size_type __rem = __size0 - __xlen - __pos;
421
422 // check for shared representation, insufficient capacity
423 if ( capacity () < __size1
424 || size_type (1) < size_type (_C_pref ()->_C_get_ref ())) {
425
426 // need to allocate a new reference
427 const size_type __cap = _C_grow (__size0, __size1);
428
429 const pointer __data = _C_get_rep (__cap, __size1)->data ();
430
431 traits_type::copy (__data, _C_data, __pos);
432
433 traits_type::assign (__data + __pos, __count, __val);
434
435 traits_type::copy (__data + (__pos + __count),
436 _C_data + (__pos + __len), __rem);
437
438 _C_unlink (__data);
439 }
440 else {
441 // current reference is not shared and has enough space
442
443 const pointer __beg = _C_data + __pos;
444
445 traits_type::move (__beg + __count, __beg + __len, __rem);
446
447 traits_type::assign (__beg, __count, __val);
448
449 // append the terminating NUL character
450 traits_type::assign (_C_data [__size1], value_type ());
451
452 _C_pref ()->_C_size._C_size = __size1;
453 }
454 }
455 else {
456 // special case a substitution that leaves the string empty.
457 clear ();
458 }
459
460 return *this;
461}
462
463
464#ifdef _RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES
465
467template <class _CharT, class _Traits, class _Alloc,
468 class _StringIter, class _InputIter>
469_STD::basic_string<_CharT, _Traits, _Alloc>&
470__rw_replace (_STD::basic_string<_CharT, _Traits, _Alloc> &__s,
471 _StringIter __first1, _StringIter __last1,
472 _InputIter __first2, _InputIter __last2) {
473
474 typedef _Traits traits_type;
475 typedef typename traits_type::char_type value_type;
476 typedef _Alloc allocator_type;
477 typedef typename allocator_type::size_type size_type;
478
479 typedef _STD::basic_string<_CharT, _Traits, _Alloc> _C_string_type;
480
481 typedef _RW::__string_ref<value_type, traits_type, allocator_type>
482 _C_string_ref_type;
483
484
485#else // !defined (_RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES)
486
487template<class _CharT, class _Traits, class _Allocator>
488template<class _InputIter>
489basic_string<_CharT, _Traits, _Allocator>&
490basic_string<_CharT, _Traits, _Allocator>::
491replace (iterator __first1, iterator __last1,
492 _InputIter __first2, _InputIter __last2, void*)
493{
494 typedef basic_string _C_string_type;
495
496 basic_string &__s = *this;
497
498#endif // _RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES
499
500 _RWSTD_ASSERT_RANGE (__first1,
501 __s._C_make_iter (__s._C_data + __s.size ()));
502 _RWSTD_ASSERT_RANGE (__first1, __last1);
503 _RWSTD_ASSERT_RANGE (__first2, __last2);
504
505 if (__first2 == __last2) {
506 if (__first1 == __last1)
507 return __s;
508
509 const size_type __pos = __s._C_off (__first1);
510 const size_type __n = __s._C_off (__first1, __last1);
511 return __s.replace (__pos, __n, size_type (), value_type ());
512 }
513
514 // use a (probably) faster algorithm if possible
515 if (_STD::__is_bidirectional_iterator (_RWSTD_ITERATOR_CATEGORY(_InputIter,
516 __last2)))
517 return __s.__replace_aux (__first1, __last1, __first2, __last2);
518
519 _C_string_type __s3;
520 typename _C_string_type::iterator __first3 = __s3.begin ();
521
522 for ( ; !(__first2 == __last2); ++__first2, ++__first3) {
523
524 const size_type __off = __s3._C_off (__first3);
525
526 _RWSTD_REQUIRES (__off <= __s3.max_size (),
528 _RWSTD_FUNC ("basic_string::replace (iterator, "
529 "iterator, InputIterator, "
530 "InputIterator)"),
531 __s3._C_off (__first3), __s3.max_size ()));
532
533 // extend the string if necessary
534 if (__s3.end () == __first3) {
535 // compute the size of new buffer
536 const size_type __cap = __s3._C_grow (__s3.size (), size_type ());
537
538 // allocate a new buffer
539 _C_string_ref_type *__tmp = __s3._C_get_rep (__cap, __cap);
540
541 // copy data from old to new, leaving a hole for additions
542 traits_type::copy (__tmp->data (), __s3._C_data, __off);
543 __s3._C_unlink (__tmp->data ());
544 __first3 = __s3._C_make_iter (__s3._C_data + __off);
545 }
546
547 // copy data over
548 traits_type::assign (*__first3, *__first2);
549 }
550
551 const size_type __size = __s3._C_off (__first3);
552 traits_type::assign (__s3._C_data [__size], value_type ());
553 __s3._C_pref ()->_C_size._C_size = __size;
554
555 return __s.__replace_aux (__first1, __last1, __s3.begin (), __s3.end ());
556}
557
558// Special function for random access and bi-directional iterators
559// Avoids the possibility of multiple allocations
560// We still have to copy characters over one at a time.
561
562#ifdef _RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES
563
565template <class _CharT, class _Traits, class _Alloc,
566 class _StringIter, class _InputIter>
567_STD::basic_string<_CharT, _Traits, _Alloc>&
568__rw_replace_aux (_STD::basic_string<_CharT, _Traits, _Alloc> &__s,
569 _StringIter __first1, _StringIter __last1,
570 _InputIter __first2, _InputIter __last2)
571{
572 typedef _Traits traits_type;
573 typedef typename traits_type::char_type value_type;
574 typedef _Alloc allocator_type;
575 typedef typename allocator_type::size_type size_type;
576 typedef typename allocator_type::difference_type difference_type;
577 typedef typename allocator_type::pointer pointer;
578 typedef typename allocator_type::const_pointer const_pointer;
579 typedef typename allocator_type::const_reference const_reference;
580
581 typedef _RW::__string_ref<value_type, traits_type, allocator_type>
582 _C_string_ref_type;
583
584#else // if !defined (_RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES)
585
586template<class _CharT, class _Traits, class _Allocator>
587template<class _InputIter>
588basic_string<_CharT, _Traits, _Allocator>&
589basic_string<_CharT, _Traits, _Allocator>::
590__replace_aux (iterator __first1, iterator __last1,
591 _InputIter __first2, _InputIter __last2)
592{
593 basic_string &__s = *this;
594
595#endif // _RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES
596
597 _RWSTD_ASSERT_RANGE (__first1, __s._C_make_iter (__s._C_data
598 + __s.size ()));
599 _RWSTD_ASSERT_RANGE (__first1, __last1);
600 _RWSTD_ASSERT_RANGE (__first2, __last2);
601
602 const size_type __n2 = _DISTANCE (__first2, __last2, size_type);
603 const size_type __n = __s._C_off (__first1, __last1);
604 const size_type __pos = __s._C_off (__first1);
605 const size_type __ssize = __s.size ();
606
607 _RWSTD_REQUIRES (__pos <= __ssize,
609 _RWSTD_FUNC ("basic_string::__replace_aux (iterator, "
610 "iterator, InputIterator, InputIterator)"),
611 __pos, __ssize));
612
613 size_type __slen = __ssize - __pos;
614 size_type __xlen = __n < __slen ? __n : __slen;
615
616 _RWSTD_REQUIRES (__ssize - __xlen <= __s.max_size () - __n2,
618 _RWSTD_FUNC ("basic_string::__replace_aux (iterator, "
619 "iterator, InputIterator, InputIterator)"),
620 __ssize - __xlen, __s.max_size () - __n2));
621
622 size_type __len = __ssize - __xlen + __n2; // Final string length.
623
624 if (!__len) {
625 // Special case a substitution that leaves the string empty.
626 __s._C_unlink (__s._C_nullref ()->data ());
627 }
628 else {
629 size_type __d = 0;
630 // length of bit at the end
631 size_type __rem = __ssize - __xlen - __pos;
632 // Check for shared representation, insufficient capacity
633 if ( __s.capacity () < __len
634 || size_type (1) < size_type (__s._C_pref ()->_C_get_ref ()))
635 {
636 // Need to allocate a new reference.
637 const size_type __cap = __s._C_grow (__ssize, __len);
638
639 _C_string_ref_type * __temp = __s._C_get_rep (__cap, __len);
640 if (__pos)
641 traits_type::copy (__temp->data (), __s._C_data, __pos);
642 for (__d = 0; __d < __n2; __d++)
643 traits_type::assign (*(__temp->data ()+__pos + __d),
644 *__first2++);
645 if (__rem)
646 traits_type::copy (__temp->data () + __pos + __n2,
647 __s._C_data + __pos + __n, __rem);
648 __s._C_unlink (__temp->data ());
649 }
650 else {
651 // Current reference has enough room.
652 if (__rem)
653 traits_type::move (__s._C_data + __pos + __n2,
654 __s._C_data + __pos + __n,
655 __rem);
656
657 for (__d = 0; __d < __n2; __d++)
658 traits_type::assign (*(__s._C_data + __pos + __d),
659 *__first2++);
660
661 __s._C_pref ()->_C_size._C_size = __len;
662 traits_type::assign (__s._C_data [__len], value_type ());
663 }
664 }
665 return __s;
666}
667
668
669template <class _CharT, class _Traits, class _Allocator>
670typename basic_string<_CharT, _Traits, _Allocator>::size_type
671basic_string<_CharT, _Traits, _Allocator>::
672copy (pointer __s, size_type __n, size_type __pos) const
673{
674 _RWSTD_REQUIRES (__pos <= size (),
676 _RWSTD_FUNC ("basic_string::copy (pointer, size_type, "
677 "size_type)"),
678 __pos, size ()));
679
680 const size_type __rlen = _C_min (size () - __pos, __n);
681
682 traits_type::copy (__s, _C_data + __pos, __rlen);
683
684 return __rlen;
685}
686
687
688template <class _CharT, class _Traits, class _Allocator>
689typename basic_string<_CharT, _Traits, _Allocator>::size_type
690basic_string<_CharT, _Traits, _Allocator>::
691find (const_pointer __seq, size_type __off, size_type __len) const
692{
693 const size_type __size = size ();
694
695 if (__size < __off)
696 return npos;
697
698 _RWSTD_ASSERT (__seq != 0 || __len == 0);
699
700 const const_pointer __end = _C_data + __size;
701 const const_pointer __seq_end = __seq + __len;
702
703 // `first' is set to point to the first occurrence of the first
704 // element of the sought sequence in the controlling sequence
705 // if one exists, otherwise to 0
706 const_pointer __first = const_pointer ();
707
708 for (const_pointer __next = _C_data + __off; ; __next = __first) {
709
710 // compute the legth of the rest of the controlling sequene
711 // and break out when it's shorter than the sought sequence
712 const size_type __ext = size_type (__end - __next);
713
714 if (__ext < __len)
715 break;
716
717 __first = const_pointer ();
718
719 for (const_pointer __n = __next, __s = __seq; ; ++__n, ++__s) {
720
721 if (__seq_end == __s)
722 return size_type (__next - _C_data);
723
724 if (traits_type::eq (*__n, *__s)) {
725 if (const_pointer () == __first && __n != __next && traits_type::eq (*__n, *__seq))
726 __first = __n;
727 }
728 else {
729 if (const_pointer () == __first) {
730 // look for the first occurrence of the first element
731 // of the sought sequence in the rest of the cotrolling
732 // sequence
733 __first = traits_type::find (__n, __end - __n, *__seq);
734
735 if (const_pointer () == __first)
736 return npos;
737 }
738 break;
739 }
740 }
741 }
742
743 return npos;
744}
745
746
747template <class _CharT, class _Traits, class _Allocator>
748typename basic_string<_CharT, _Traits, _Allocator>::size_type
749basic_string<_CharT, _Traits, _Allocator>::
750rfind (const_pointer __s, size_type __pos, size_type __n) const
751{
752 _RWSTD_ASSERT (__s != 0);
753
754 if (size () < __n)
755 return npos;
756
757 size_type __slen = size () - __n;
758 size_type __xpos_start = __slen < __pos ? __slen : __pos;
759
760 for (size_type __xpos = __xpos_start + 1; __xpos != 0 ; __xpos--) {
761 if (!traits_type::compare (_C_data + __xpos - 1, __s, __n))
762 return __xpos - 1;
763 }
764
765 return npos;
766}
767
768
769template <class _CharT, class _Traits, class _Allocator>
770typename basic_string<_CharT, _Traits, _Allocator>::size_type
771basic_string<_CharT, _Traits, _Allocator>::
772find_first_of (const_pointer __s, size_type __pos, size_type __n) const
773{
774 _RWSTD_ASSERT (__s != 0);
775
776 for (size_type __xpos = __pos; __xpos < size () ; __xpos++) {
777 for (size_type __i = 0; __i < __n ; __i++)
778 if (traits_type::eq (_C_data [__xpos], __s [__i]))
779 return __xpos;
780 }
781
782 return npos;
783}
784
785
786template <class _CharT, class _Traits, class _Allocator>
787typename basic_string<_CharT, _Traits, _Allocator>::size_type
788basic_string<_CharT, _Traits, _Allocator>::
789find_last_of (const_pointer __s, size_type __pos, size_type __n) const
790{
791 _RWSTD_ASSERT (__s != 0);
792
793 if (size ()) {
794 size_type __slen = size () - 1;
795 size_type __xpos_start = __pos < __slen ? __pos : __slen;
796 for (size_type __xpos = __xpos_start+1; __xpos != 0 ; __xpos--) {
797 for (size_type __i = 0; __i < __n ; __i++)
798 if (traits_type::eq (_C_data [__xpos - 1], __s [__i]))
799 return __xpos - 1;
800 }
801 }
802
803 return npos;
804}
805
806
807template <class _CharT, class _Traits, class _Allocator>
808typename basic_string<_CharT, _Traits, _Allocator>::size_type
809basic_string<_CharT, _Traits, _Allocator>::
810find_first_not_of (const_pointer __s, size_type __pos, size_type __n) const
811{
812 _RWSTD_ASSERT (__s != 0);
813
814 for (size_type __xpos = __pos; __xpos < size () ; __xpos++) {
815 bool __found = false;
816 for (size_type __i = 0; __i < __n ; __i++) {
817 if (traits_type::eq (_C_data [__xpos], __s [__i])) {
818 __found = true;
819 break;
820 }
821 }
822 if (!__found)
823 return __xpos;
824 }
825
826 return npos;
827}
828
829
830template <class _CharT, class _Traits, class _Allocator>
831typename basic_string<_CharT, _Traits, _Allocator>::size_type
832basic_string<_CharT, _Traits, _Allocator>::
833find_last_not_of (const_pointer __s, size_type __pos, size_type __n) const
834{
835 _RWSTD_ASSERT (__s != 0);
836
837 if (size ()) {
838 size_type __slen = size () - 1;
839 size_type __xpos_start = __pos < __slen ? __pos : __slen;
840 for (size_type __xpos = __xpos_start + 1; __xpos != 0 ; __xpos--) {
841 bool __found = false;
842 for (size_type __i = 0; __i < __n ; __i++) {
843 if (traits_type::eq (_C_data [__xpos - 1], __s [__i])) {
844 __found = true;
845 break;
846 }
847 }
848 if (!__found)
849 return __xpos - 1;
850 }
851 }
852
853 return npos;
854}
855
856
857template <class _CharT, class _Traits, class _Allocator>
858basic_string<_CharT, _Traits, _Allocator>
859basic_string<_CharT, _Traits, _Allocator>::
860substr (size_type __pos, size_type __n) const
861{
862 _RWSTD_REQUIRES (__pos <= size (),
864 _RWSTD_FUNC ("basic_string::substr (size_type, "
865 "size_type) const"),
866 __pos, size ()));
867
868 size_type __slen = size () - __pos;
869 size_type __rlen = __n < __slen ? __n : __slen;
870 return basic_string (_C_data + __pos, __rlen);
871}
872
873
874template <class _CharT, class _Traits, class _Allocator>
875int basic_string<_CharT, _Traits, _Allocator>::
876compare (size_type __pos1, size_type __n1,
877 const basic_string& __str, size_type __pos2, size_type __n2) const
878{
879 _RWSTD_REQUIRES (__pos2 <= __str.size (),
881 _RWSTD_FUNC ("basic_string::compare (size_type, "
882 "size_type, const basic_string&, "
883 "size_type, size_type) const"),
884 __pos2, __str.size ()));
885
886 if (__str.size () - __pos2 < __n2)
887 __n2 = __str.size () - __pos2;
888
889 return compare (__pos1, __n1, __str.c_str () + __pos2, __n2);
890}
891
892
893template <class _CharT, class _Traits, class _Allocator>
894int basic_string<_CharT, _Traits, _Allocator>::
895compare (size_type __pos, size_type __n1,
896 const_pointer __s, size_type __n2) const
897{
898 _RWSTD_REQUIRES (__pos <= size (),
900 _RWSTD_FUNC ("basic_string::compare (size_type, "
901 "size_type, const const_pointer, "
902 "size_type) const"),
903 __pos, size ()));
904
905 if (size () - __pos < __n1)
906 __n1 = size () - __pos;
907 size_type __rlen = __n1 < __n2 ? __n1 : __n2;
908 int __res = traits_type::compare (_C_data + __pos, __s, __rlen);
909
910 if (__res == 0)
911 __res = (__n1 < __n2) ? -1 : (__n1 != __n2);
912
913 return __res;
914}
915
916
917} // namespace std
918
919
920#ifdef _RWSTD_MSVC
921# pragma warning (pop)
922#endif // _RWSTD_MSVC
const char *const data[]
#define _RWSTD_REQUIRES(pred, args)
Definition _defs.h:1132
#define _RWSTD_VALUE_ALLOC(ignore, object, call)
Definition _defs.h:893
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_FUNC(ignore)
Definition _defs.h:1120
#define _EXPORT
Definition _defs.h:498
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _DISTANCE(first, last, ignore)
Definition _defs.h:1225
#define _RWSTD_ASSERT_RANGE(ign1, ign2)
Definition _defs.h:1247
#define _RWSTD_ITERATOR_CATEGORY(iterT, ignore)
Definition _defs.h:1055
#define _RWSTD_ERROR_LENGTH_ERROR
Definition _error.h:92
#define _RWSTD_ERROR_OUT_OF_RANGE
Definition _error.h:93
Definition json.h:5363