117 #ifndef EASTL_STRING_H
118 #define EASTL_STRING_H
121 #include <stk_util/util/config_eastl.h>
122 #if EASTL_ABSTRACT_STRING_ENABLED
123 #include <EASTL/bonus/string_abstract.h>
124 #else // 'else' encompasses the entire rest of this file.
125 #include <stk_util/util/allocator_eastl.h>
126 #include <stk_util/util/iterator_eastl.h>
127 #include <stk_util/util/algorithm_eastl.h>
130 #pragma warning(push, 0)
139 #include <../Include/string.h>
147 #if EASTL_EXCEPTIONS_ENABLED
149 #pragma warning(push, 0)
158 #pragma warning(push)
159 #pragma warning(disable: 4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
160 #pragma warning(disable: 4267) // 'argument' : conversion from 'size_t' to 'const uint32_t', possible loss of data. This is a bogus warning resulting from a bug in VC++.
161 #pragma warning(disable: 4480) // nonstandard extension used: specifying underlying type for enum
170 #if EASTL_STRING_OPT_EXPLICIT_CTORS
171 #define EASTL_STRING_EXPLICIT explicit
173 #define EASTL_STRING_EXPLICIT
185 const eastl_size_t EASTL_STRING_INITIAL_CAPACITY = 8;
197 extern int Vsnprintf8 (char8_t* pDestination,
size_t n,
const char8_t* pFormat, va_list arguments);
198 extern int Vsnprintf16(char16_t* pDestination,
size_t n,
const char16_t* pFormat, va_list arguments);
199 extern int Vsnprintf32(char32_t* pDestination,
size_t n,
const char32_t* pFormat, va_list arguments);
203 inline int Vsnprintf(char8_t* pDestination,
size_t n,
const char8_t* pFormat, va_list arguments)
204 {
return Vsnprintf8(pDestination, n, pFormat, arguments); }
206 inline int Vsnprintf(char16_t* pDestination,
size_t n,
const char16_t* pFormat, va_list arguments)
207 {
return Vsnprintf16(pDestination, n, pFormat, arguments); }
209 inline int Vsnprintf(char32_t* pDestination,
size_t n,
const char32_t* pFormat, va_list arguments)
210 {
return Vsnprintf32(pDestination, n, pFormat, arguments); }
223 #ifndef EASTL_BASIC_STRING_DEFAULT_NAME
224 #define EASTL_BASIC_STRING_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " basic_string" // Unless the user overrides something, this is "EASTL basic_string".
230 #ifndef EASTL_BASIC_STRING_DEFAULT_ALLOCATOR
231 #define EASTL_BASIC_STRING_DEFAULT_ALLOCATOR allocator_type(EASTL_BASIC_STRING_DEFAULT_NAME)
244 unsigned char mEmptyU8[1];
245 signed char mEmptyS8[1];
246 char16_t mEmpty16[1];
247 char32_t mEmpty32[1];
251 inline const signed char* GetEmptyString(
signed char) {
return gEmptyString.mEmptyS8; }
252 inline const unsigned char* GetEmptyString(
unsigned char) {
return gEmptyString.mEmptyU8; }
253 inline const char* GetEmptyString(
char) {
return gEmptyString.mEmpty8; }
254 inline const char16_t* GetEmptyString(char16_t) {
return gEmptyString.mEmpty16; }
255 inline const char32_t* GetEmptyString(char32_t) {
return gEmptyString.mEmpty32; }
271 template <
typename T,
typename Allocator = EASTLAllocatorType>
276 typedef T value_type;
278 typedef const T* const_pointer;
279 typedef T& reference;
280 typedef const T& const_reference;
282 typedef const T* const_iterator;
285 typedef eastl_size_t size_type;
286 typedef ptrdiff_t difference_type;
287 typedef Allocator allocator_type;
289 #if defined(_MSC_VER) && (_MSC_VER >= 1400) // _MSC_VER of 1400 means VC8 (VS2005), 1500 means VC9 (VS2008)
291 npos = (size_type)-1,
295 static const size_type npos = (size_type)-1;
301 kAlignment = EASTL_ALIGN_OF(T),
308 struct CtorDoNotInitialize{};
312 struct CtorSprintf{};
317 value_type* mpCapacity;
318 allocator_type mAllocator;
323 explicit basic_string(
const allocator_type& allocator);
324 basic_string(
const this_type& x, size_type position, size_type n = npos);
325 basic_string(
const value_type* p, size_type n,
const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR);
326 EASTL_STRING_EXPLICIT basic_string(
const value_type* p,
const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR);
327 basic_string(size_type n, value_type c,
const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR);
328 basic_string(
const this_type& x);
329 basic_string(
const value_type* pBegin,
const value_type* pEnd,
const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR);
330 basic_string(CtorDoNotInitialize, size_type n,
const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR);
331 basic_string(CtorSprintf,
const value_type* pFormat, ...);
336 const allocator_type& get_allocator()
const;
337 allocator_type& get_allocator();
338 void set_allocator(
const allocator_type& allocator);
341 this_type& operator=(
const this_type& x);
342 this_type& operator=(
const value_type* p);
343 this_type& operator=(value_type c);
345 void swap(this_type& x);
348 basic_string& assign(
const basic_string& x);
349 basic_string& assign(
const basic_string& x, size_type position, size_type n);
350 basic_string& assign(
const value_type* p, size_type n);
351 basic_string& assign(
const value_type* p);
352 basic_string& assign(size_type n, value_type c);
353 basic_string& assign(
const value_type* pBegin,
const value_type* pEnd);
357 const_iterator begin()
const;
359 const_iterator end()
const;
361 reverse_iterator rbegin();
362 const_reverse_iterator rbegin()
const;
363 reverse_iterator rend();
364 const_reverse_iterator rend()
const;
368 size_type size()
const;
369 size_type length()
const;
370 size_type max_size()
const;
371 size_type capacity()
const;
372 void resize(size_type n, value_type c);
373 void resize(size_type n);
374 void reserve(size_type = 0);
375 void set_capacity(size_type n = npos);
376 void force_size(size_type n);
379 const value_type* data()
const;
380 const value_type* c_str()
const;
383 reference operator[](size_type n);
384 const_reference operator[](size_type n)
const;
385 reference at(size_type n);
386 const_reference at(size_type n)
const;
388 const_reference front()
const;
390 const_reference back()
const;
393 basic_string& operator+=(
const basic_string& x);
394 basic_string& operator+=(
const value_type* p);
395 basic_string& operator+=(value_type c);
397 basic_string& append(
const basic_string& x);
398 basic_string& append(
const basic_string& x, size_type position, size_type n);
399 basic_string& append(
const value_type* p, size_type n);
400 basic_string& append(
const value_type* p);
401 basic_string& append(size_type n, value_type c);
402 basic_string& append(
const value_type* pBegin,
const value_type* pEnd);
404 basic_string& append_sprintf_va_list(
const value_type* pFormat, va_list arguments);
405 basic_string& append_sprintf(
const value_type* pFormat, ...);
407 void push_back(value_type c);
411 basic_string& insert(size_type position,
const basic_string& x);
412 basic_string& insert(size_type position,
const basic_string& x, size_type beg, size_type n);
413 basic_string& insert(size_type position,
const value_type* p, size_type n);
414 basic_string& insert(size_type position,
const value_type* p);
415 basic_string& insert(size_type position, size_type n, value_type c);
416 iterator insert(iterator p, value_type c);
417 void insert(iterator p, size_type n, value_type c);
418 void insert(iterator p,
const value_type* pBegin,
const value_type* pEnd);
421 basic_string& erase(size_type position = 0, size_type n = npos);
422 iterator erase(iterator p);
423 iterator erase(iterator pBegin, iterator pEnd);
424 reverse_iterator erase(reverse_iterator position);
425 reverse_iterator erase(reverse_iterator first, reverse_iterator last);
430 basic_string& replace(size_type position, size_type n,
const basic_string& x);
431 basic_string& replace(size_type pos1, size_type n1,
const basic_string& x, size_type pos2, size_type n2);
432 basic_string& replace(size_type position, size_type n1,
const value_type* p, size_type n2);
433 basic_string& replace(size_type position, size_type n1,
const value_type* p);
434 basic_string& replace(size_type position, size_type n1, size_type n2, value_type c);
435 basic_string& replace(iterator first, iterator last,
const basic_string& x);
436 basic_string& replace(iterator first, iterator last,
const value_type* p, size_type n);
437 basic_string& replace(iterator first, iterator last,
const value_type* p);
438 basic_string& replace(iterator first, iterator last, size_type n, value_type c);
439 basic_string& replace(iterator first, iterator last,
const value_type* pBegin,
const value_type* pEnd);
440 size_type copy(value_type* p, size_type n, size_type position = 0)
const;
443 size_type find(
const basic_string& x, size_type position = 0)
const;
444 size_type find(
const value_type* p, size_type position = 0)
const;
445 size_type find(
const value_type* p, size_type position, size_type n)
const;
446 size_type find(value_type c, size_type position = 0)
const;
449 size_type rfind(
const basic_string& x, size_type position = npos)
const;
450 size_type rfind(
const value_type* p, size_type position = npos)
const;
451 size_type rfind(
const value_type* p, size_type position, size_type n)
const;
452 size_type rfind(value_type c, size_type position = npos)
const;
455 size_type find_first_of(
const basic_string& x, size_type position = 0)
const;
456 size_type find_first_of(
const value_type* p, size_type position = 0)
const;
457 size_type find_first_of(
const value_type* p, size_type position, size_type n)
const;
458 size_type find_first_of(value_type c, size_type position = 0)
const;
461 size_type find_last_of(
const basic_string& x, size_type position = npos)
const;
462 size_type find_last_of(
const value_type* p, size_type position = npos)
const;
463 size_type find_last_of(
const value_type* p, size_type position, size_type n)
const;
464 size_type find_last_of(value_type c, size_type position = npos)
const;
467 size_type find_first_not_of(
const basic_string& x, size_type position = 0)
const;
468 size_type find_first_not_of(
const value_type* p, size_type position = 0)
const;
469 size_type find_first_not_of(
const value_type* p, size_type position, size_type n)
const;
470 size_type find_first_not_of(value_type c, size_type position = 0)
const;
473 size_type find_last_not_of(
const basic_string& x, size_type position = npos)
const;
474 size_type find_last_not_of(
const value_type* p, size_type position = npos)
const;
475 size_type find_last_not_of(
const value_type* p, size_type position, size_type n)
const;
476 size_type find_last_not_of(value_type c, size_type position = npos)
const;
479 basic_string substr(size_type position = 0, size_type n = npos)
const;
482 int compare(
const basic_string& x)
const;
483 int compare(size_type pos1, size_type n1,
const basic_string& x)
const;
484 int compare(size_type pos1, size_type n1,
const basic_string& x, size_type pos2, size_type n2)
const;
485 int compare(
const value_type* p)
const;
486 int compare(size_type pos1, size_type n1,
const value_type* p)
const;
487 int compare(size_type pos1, size_type n1,
const value_type* p, size_type n2)
const;
488 static int compare(
const value_type* pBegin1,
const value_type* pEnd1,
const value_type* pBegin2,
const value_type* pEnd2);
491 int comparei(
const basic_string& x)
const;
492 int comparei(
const value_type* p)
const;
493 static int comparei(
const value_type* pBegin1,
const value_type* pEnd1,
const value_type* pBegin2,
const value_type* pEnd2);
501 basic_string left(size_type n)
const;
502 basic_string right(size_type n)
const;
503 basic_string& sprintf_va_list(
const value_type* pFormat, va_list arguments);
504 basic_string& sprintf(
const value_type* pFormat, ...);
506 bool validate()
const;
507 int validate_iterator(const_iterator i)
const;
511 value_type* DoAllocate(size_type n);
512 void DoFree(value_type* p, size_type n);
513 size_type GetNewCapacity(size_type currentCapacity);
516 void AllocateSelf(size_type n);
517 void DeallocateSelf();
518 iterator InsertInternal(iterator p, value_type c);
519 void RangeInitialize(
const value_type* pBegin,
const value_type* pEnd);
520 void RangeInitialize(
const value_type* pBegin);
521 void SizeInitialize(size_type n, value_type c);
522 void ThrowLengthException()
const;
523 void ThrowRangeException()
const;
524 void ThrowInvalidArgumentException()
const;
527 static const value_type* CharTypeStringFindEnd(
const value_type* pBegin,
const value_type* pEnd, value_type c);
528 static const value_type* CharTypeStringRFind(
const value_type* pRBegin,
const value_type* pREnd,
const value_type c);
529 static const value_type* CharTypeStringSearch(
const value_type* p1Begin,
const value_type* p1End,
const value_type* p2Begin,
const value_type* p2End);
530 static const value_type* CharTypeStringRSearch(
const value_type* p1Begin,
const value_type* p1End,
const value_type* p2Begin,
const value_type* p2End);
531 static const value_type* CharTypeStringFindFirstOf(
const value_type* p1Begin,
const value_type* p1End,
const value_type* p2Begin,
const value_type* p2End);
532 static const value_type* CharTypeStringRFindFirstOf(
const value_type* p1RBegin,
const value_type* p1REnd,
const value_type* p2Begin,
const value_type* p2End);
533 static const value_type* CharTypeStringFindFirstNotOf(
const value_type* p1Begin,
const value_type* p1End,
const value_type* p2Begin,
const value_type* p2End);
534 static const value_type* CharTypeStringRFindFirstNotOf(
const value_type* p1RBegin,
const value_type* p1REnd,
const value_type* p2Begin,
const value_type* p2End);
544 inline char8_t CharToLower(char8_t c)
545 {
return (char8_t)tolower((uint8_t)c); }
547 inline char16_t CharToLower(char16_t c)
548 {
if((
unsigned)c <= 0xff)
return (char16_t)tolower((uint8_t)c);
return c; }
550 inline char32_t CharToLower(char32_t c)
551 {
if((
unsigned)c <= 0xff)
return (char32_t)tolower((uint8_t)c);
return c; }
555 inline char8_t CharToUpper(char8_t c)
556 {
return (char8_t)toupper((uint8_t)c); }
558 inline char16_t CharToUpper(char16_t c)
559 {
if((
unsigned)c <= 0xff)
return (char16_t)toupper((uint8_t)c);
return c; }
561 inline char32_t CharToUpper(char32_t c)
562 {
if((
unsigned)c <= 0xff)
return (char32_t)toupper((uint8_t)c);
return c; }
566 template <
typename T>
567 int Compare(
const T* p1,
const T* p2,
size_t n)
569 for(; n > 0; ++p1, ++p2, --n)
572 return (*p1 < *p2) ? -1 : 1;
577 inline int Compare(
const char8_t* p1,
const char8_t* p2,
size_t n)
579 return memcmp(p1, p2, n);
582 template <
typename T>
583 inline int CompareI(
const T* p1,
const T* p2,
size_t n)
585 for(; n > 0; ++p1, ++p2, --n)
587 const T c1 = CharToLower(*p1);
588 const T c2 = CharToLower(*p2);
591 return (c1 < c2) ? -1 : 1;
597 inline const char8_t* Find(
const char8_t* p, char8_t c,
size_t n)
599 return (
const char8_t*)memchr(p, c, n);
602 inline const char16_t* Find(
const char16_t* p, char16_t c,
size_t n)
604 for(; n > 0; --n, ++p)
613 inline const char32_t* Find(
const char32_t* p, char32_t c,
size_t n)
615 for(; n > 0; --n, ++p)
625 inline size_t CharStrlen(
const char8_t* p)
627 #ifdef _MSC_VER // VC++ can implement an instrinsic here.
630 const char8_t* pCurrent = p;
633 return (
size_t)(pCurrent - p);
637 inline size_t CharStrlen(
const char16_t* p)
639 const char16_t* pCurrent = p;
642 return (
size_t)(pCurrent - p);
645 inline size_t CharStrlen(
const char32_t* p)
647 const char32_t* pCurrent = p;
650 return (
size_t)(pCurrent - p);
654 template <
typename T>
655 inline T* CharStringUninitializedCopy(
const T* pSource,
const T* pSourceEnd, T* pDestination)
657 memmove(pDestination, pSource, (
size_t)(pSourceEnd - pSource) *
sizeof(T));
658 return pDestination + (pSourceEnd - pSource);
664 inline char8_t* CharStringUninitializedFillN(char8_t* pDestination,
size_t n,
const char8_t c)
667 memset(pDestination, (uint8_t)c, (
size_t)n);
668 return pDestination + n;
671 inline char16_t* CharStringUninitializedFillN(char16_t* pDestination,
size_t n,
const char16_t c)
673 char16_t* pDest16 = pDestination;
674 const char16_t*
const pEnd = pDestination + n;
675 while(pDest16 < pEnd)
677 return pDestination + n;
680 inline char32_t* CharStringUninitializedFillN(char32_t* pDestination,
size_t n,
const char32_t c)
682 char32_t* pDest32 = pDestination;
683 const char32_t*
const pEnd = pDestination + n;
684 while(pDest32 < pEnd)
686 return pDestination + n;
691 inline char8_t* CharTypeAssignN(char8_t* pDestination,
size_t n, char8_t c)
694 return (char8_t*)memset(pDestination, c, (
size_t)n);
698 inline char16_t* CharTypeAssignN(char16_t* pDestination,
size_t n, char16_t c)
700 char16_t* pDest16 = pDestination;
701 const char16_t*
const pEnd = pDestination + n;
702 while(pDest16 < pEnd)
707 inline char32_t* CharTypeAssignN(char32_t* pDestination,
size_t n, char32_t c)
709 char32_t* pDest32 = pDestination;
710 const char32_t*
const pEnd = pDestination + n;
711 while(pDest32 < pEnd)
722 template <
typename T,
typename Allocator>
723 inline basic_string<T, Allocator>::basic_string()
727 mAllocator(EASTL_BASIC_STRING_DEFAULT_NAME)
733 template <
typename T,
typename Allocator>
734 inline basic_string<T, Allocator>::basic_string(
const allocator_type& allocator)
738 mAllocator(allocator)
744 template <
typename T,
typename Allocator>
745 inline basic_string<T, Allocator>::basic_string(
const this_type& x)
749 mAllocator(x.mAllocator)
751 RangeInitialize(x.mpBegin, x.mpEnd);
755 template <
typename T,
typename Allocator>
756 basic_string<T, Allocator>::basic_string(
const this_type& x, size_type position, size_type n)
760 mAllocator(x.mAllocator)
762 #if EASTL_STRING_OPT_RANGE_ERRORS
763 if(EASTL_UNLIKELY(position > (size_type)(x.mpEnd - x.mpBegin)))
765 ThrowRangeException();
769 RangeInitialize(x.mpBegin + position, x.mpBegin + position +
eastl::min_alt(n, (size_type)(x.mpEnd - x.mpBegin) - position));
771 RangeInitialize(x.mpBegin + position, x.mpBegin + position +
eastl::min_alt(n, (size_type)(x.mpEnd - x.mpBegin) - position));
776 template <
typename T,
typename Allocator>
777 inline basic_string<T, Allocator>::basic_string(
const value_type* p, size_type n,
const allocator_type& allocator)
781 mAllocator(allocator)
783 RangeInitialize(p, p + n);
787 template <
typename T,
typename Allocator>
788 inline basic_string<T, Allocator>::basic_string(
const value_type* p,
const allocator_type& allocator)
792 mAllocator(allocator)
798 template <
typename T,
typename Allocator>
799 inline basic_string<T, Allocator>::basic_string(size_type n, value_type c,
const allocator_type& allocator)
803 mAllocator(allocator)
805 SizeInitialize(n, c);
809 template <
typename T,
typename Allocator>
810 inline basic_string<T, Allocator>::basic_string(
const value_type* pBegin,
const value_type* pEnd,
const allocator_type& allocator)
814 mAllocator(allocator)
816 RangeInitialize(pBegin, pEnd);
822 template <
typename T,
typename Allocator>
823 basic_string<T, Allocator>::basic_string(CtorDoNotInitialize , size_type n,
const allocator_type& allocator)
827 mAllocator(allocator)
837 template <
typename T,
typename Allocator>
838 basic_string<T, Allocator>::basic_string(CtorSprintf ,
const value_type* pFormat, ...)
844 const size_type n = (size_type)CharStrlen(pFormat) + 1;
848 va_start(arguments, pFormat);
849 append_sprintf_va_list(pFormat, arguments);
854 template <
typename T,
typename Allocator>
855 inline basic_string<T, Allocator>::~basic_string()
861 template <
typename T,
typename Allocator>
862 inline const typename basic_string<T, Allocator>::allocator_type&
863 basic_string<T, Allocator>::get_allocator()
const
869 template <
typename T,
typename Allocator>
870 inline typename basic_string<T, Allocator>::allocator_type&
871 basic_string<T, Allocator>::get_allocator()
877 template <
typename T,
typename Allocator>
878 inline void basic_string<T, Allocator>::set_allocator(
const allocator_type& allocator)
880 mAllocator = allocator;
884 template <
typename T,
typename Allocator>
885 inline const typename basic_string<T, Allocator>::value_type*
886 basic_string<T, Allocator>::data()
const
892 template <
typename T,
typename Allocator>
893 inline const typename basic_string<T, Allocator>::value_type*
894 basic_string<T, Allocator>::c_str()
const
900 template <
typename T,
typename Allocator>
901 inline typename basic_string<T, Allocator>::iterator
902 basic_string<T, Allocator>::begin()
908 template <
typename T,
typename Allocator>
909 inline typename basic_string<T, Allocator>::iterator
910 basic_string<T, Allocator>::end()
916 template <
typename T,
typename Allocator>
917 inline typename basic_string<T, Allocator>::const_iterator
918 basic_string<T, Allocator>::begin()
const
924 template <
typename T,
typename Allocator>
925 inline typename basic_string<T, Allocator>::const_iterator
926 basic_string<T, Allocator>::end()
const
932 template <
typename T,
typename Allocator>
933 inline typename basic_string<T, Allocator>::reverse_iterator
934 basic_string<T, Allocator>::rbegin()
936 return reverse_iterator(mpEnd);
940 template <
typename T,
typename Allocator>
941 inline typename basic_string<T, Allocator>::reverse_iterator
942 basic_string<T, Allocator>::rend()
944 return reverse_iterator(mpBegin);
948 template <
typename T,
typename Allocator>
949 inline typename basic_string<T, Allocator>::const_reverse_iterator
950 basic_string<T, Allocator>::rbegin()
const
952 return const_reverse_iterator(mpEnd);
956 template <
typename T,
typename Allocator>
957 inline typename basic_string<T, Allocator>::const_reverse_iterator
958 basic_string<T, Allocator>::rend()
const
960 return const_reverse_iterator(mpBegin);
964 template <
typename T,
typename Allocator>
965 inline bool basic_string<T, Allocator>::empty()
const
967 return (mpBegin == mpEnd);
971 template <
typename T,
typename Allocator>
972 inline typename basic_string<T, Allocator>::size_type
973 basic_string<T, Allocator>::size()
const
975 return (size_type)(mpEnd - mpBegin);
979 template <
typename T,
typename Allocator>
980 inline typename basic_string<T, Allocator>::size_type
981 basic_string<T, Allocator>::length()
const
983 return (size_type)(mpEnd - mpBegin);
987 template <
typename T,
typename Allocator>
988 inline typename basic_string<T, Allocator>::size_type
989 basic_string<T, Allocator>::max_size()
const
995 template <
typename T,
typename Allocator>
996 inline typename basic_string<T, Allocator>::size_type
997 basic_string<T, Allocator>::capacity()
const
999 return (size_type)((mpCapacity - mpBegin) - 1);
1003 template <
typename T,
typename Allocator>
1004 inline typename basic_string<T, Allocator>::const_reference
1005 basic_string<T, Allocator>::operator[](size_type n)
const
1007 #if EASTL_ASSERT_ENABLED // We allow the user to reference the trailing 0 char without asserting. Perhaps we shouldn't.
1008 if(EASTL_UNLIKELY(n > (static_cast<size_type>(mpEnd - mpBegin))))
1009 EASTL_FAIL_MSG(
"basic_string::operator[] -- out of range");
1016 template <
typename T,
typename Allocator>
1017 inline typename basic_string<T, Allocator>::reference
1018 basic_string<T, Allocator>::operator[](size_type n)
1020 #if EASTL_ASSERT_ENABLED // We allow the user to reference the trailing 0 char without asserting. Perhaps we shouldn't.
1021 if(EASTL_UNLIKELY(n > (static_cast<size_type>(mpEnd - mpBegin))))
1022 EASTL_FAIL_MSG(
"basic_string::operator[] -- out of range");
1029 template <
typename T,
typename Allocator>
1030 inline typename basic_string<T, Allocator>::this_type& basic_string<T, Allocator>::operator=(
const basic_string<T, Allocator>& x)
1034 #if EASTL_ALLOCATOR_COPY_ENABLED
1035 mAllocator = x.mAllocator;
1038 assign(x.mpBegin, x.mpEnd);
1044 template <
typename T,
typename Allocator>
1045 inline typename basic_string<T, Allocator>::this_type& basic_string<T, Allocator>::operator=(
const value_type* p)
1047 return assign(p, p + CharStrlen(p));
1051 template <
typename T,
typename Allocator>
1052 inline typename basic_string<T, Allocator>::this_type& basic_string<T, Allocator>::operator=(value_type c)
1054 return assign((size_type)1, c);
1058 template <
typename T,
typename Allocator>
1059 void basic_string<T, Allocator>::resize(size_type n, value_type c)
1061 const size_type s = (size_type)(mpEnd - mpBegin);
1064 erase(mpBegin + n, mpEnd);
1070 template <
typename T,
typename Allocator>
1071 void basic_string<T, Allocator>::resize(size_type n)
1078 const size_type s = (size_type)(mpEnd - mpBegin);
1081 erase(mpBegin + n, mpEnd);
1084 #if EASTL_STRING_OPT_CHAR_INIT
1085 append(n - s, value_type());
1093 template <
typename T,
typename Allocator>
1094 void basic_string<T, Allocator>::reserve(size_type n)
1096 #if EASTL_STRING_OPT_LENGTH_ERRORS
1097 if(EASTL_UNLIKELY(n > kMaxSize))
1098 ThrowLengthException();
1112 if(n >= (size_type)(mpCapacity - mpBegin))
1117 template <
typename T,
typename Allocator>
1118 inline void basic_string<T, Allocator>::set_capacity(size_type n)
1121 n = (size_type)(mpEnd - mpBegin);
1122 else if(n < (size_type)(mpEnd - mpBegin))
1123 mpEnd = mpBegin + n;
1125 if(n != (size_type)((mpCapacity - mpBegin) - 1))
1129 pointer pNewBegin = DoAllocate(n + 1);
1130 pointer pNewEnd = pNewBegin;
1132 pNewEnd = CharStringUninitializedCopy(mpBegin, mpEnd, pNewBegin);
1136 mpBegin = pNewBegin;
1138 mpCapacity = pNewBegin + (n + 1);
1149 template <
typename T,
typename Allocator>
1150 inline void basic_string<T, Allocator>::force_size(size_type n)
1152 #if EASTL_STRING_OPT_RANGE_ERRORS
1153 if(EASTL_UNLIKELY(n >= (size_type)(mpCapacity - mpBegin)))
1154 ThrowRangeException();
1155 #elif EASTL_ASSERT_ENABLED
1156 if(EASTL_UNLIKELY(n >= (size_type)(mpCapacity - mpBegin)))
1157 EASTL_FAIL_MSG(
"basic_string::force_size -- out of range");
1160 mpEnd = mpBegin + n;
1164 template <
typename T,
typename Allocator>
1165 inline void basic_string<T, Allocator>::clear()
1167 if(mpBegin != mpEnd)
1169 *mpBegin = value_type(0);
1175 template <
typename T,
typename Allocator>
1176 inline void basic_string<T, Allocator>::reset()
1186 template <
typename T,
typename Allocator>
1187 inline typename basic_string<T, Allocator>::const_reference
1188 basic_string<T, Allocator>::at(size_type n)
const
1190 #if EASTL_STRING_OPT_RANGE_ERRORS
1191 if(EASTL_UNLIKELY(n >= (size_type)(mpEnd - mpBegin)))
1192 ThrowRangeException();
1193 #elif EASTL_ASSERT_ENABLED // We assert if the user references the trailing 0 char.
1194 if(EASTL_UNLIKELY(n >= (size_type)(mpEnd - mpBegin)))
1195 EASTL_FAIL_MSG(
"basic_string::at -- out of range");
1202 template <
typename T,
typename Allocator>
1203 inline typename basic_string<T, Allocator>::reference
1204 basic_string<T, Allocator>::at(size_type n)
1206 #if EASTL_STRING_OPT_RANGE_ERRORS
1207 if(EASTL_UNLIKELY(n >= (size_type)(mpEnd - mpBegin)))
1208 ThrowRangeException();
1209 #elif EASTL_ASSERT_ENABLED // We assert if the user references the trailing 0 char.
1210 if(EASTL_UNLIKELY(n >= (size_type)(mpEnd - mpBegin)))
1211 EASTL_FAIL_MSG(
"basic_string::at -- out of range");
1218 template <
typename T,
typename Allocator>
1219 inline typename basic_string<T, Allocator>::reference
1220 basic_string<T, Allocator>::front()
1222 #if EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
1224 #elif EASTL_ASSERT_ENABLED
1225 if(EASTL_UNLIKELY(mpEnd <= mpBegin))
1226 EASTL_FAIL_MSG(
"basic_string::front -- empty string");
1233 template <
typename T,
typename Allocator>
1234 inline typename basic_string<T, Allocator>::const_reference
1235 basic_string<T, Allocator>::front()
const
1237 #if EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
1239 #elif EASTL_ASSERT_ENABLED
1240 if(EASTL_UNLIKELY(mpEnd <= mpBegin))
1241 EASTL_FAIL_MSG(
"basic_string::front -- empty string");
1248 template <
typename T,
typename Allocator>
1249 inline typename basic_string<T, Allocator>::reference
1250 basic_string<T, Allocator>::back()
1252 #if EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
1254 #elif EASTL_ASSERT_ENABLED
1255 if(EASTL_UNLIKELY(mpEnd <= mpBegin))
1256 EASTL_FAIL_MSG(
"basic_string::back -- empty string");
1259 return *(mpEnd - 1);
1263 template <
typename T,
typename Allocator>
1264 inline typename basic_string<T, Allocator>::const_reference
1265 basic_string<T, Allocator>::back()
const
1267 #if EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
1269 #elif EASTL_ASSERT_ENABLED
1270 if(EASTL_UNLIKELY(mpEnd <= mpBegin))
1271 EASTL_FAIL_MSG(
"basic_string::back -- empty string");
1274 return *(mpEnd - 1);
1278 template <
typename T,
typename Allocator>
1279 inline basic_string<T, Allocator>& basic_string<T, Allocator>::operator+=(
const basic_string<T, Allocator>& x)
1285 template <
typename T,
typename Allocator>
1286 inline basic_string<T, Allocator>& basic_string<T, Allocator>::operator+=(
const value_type* p)
1292 template <
typename T,
typename Allocator>
1293 inline basic_string<T, Allocator>& basic_string<T, Allocator>::operator+=(value_type c)
1300 template <
typename T,
typename Allocator>
1301 inline basic_string<T, Allocator>& basic_string<T, Allocator>::append(
const basic_string<T, Allocator>& x)
1303 return append(x.mpBegin, x.mpEnd);
1307 template <
typename T,
typename Allocator>
1308 inline basic_string<T, Allocator>& basic_string<T, Allocator>::append(
const basic_string<T, Allocator>& x, size_type position, size_type n)
1310 #if EASTL_STRING_OPT_RANGE_ERRORS
1311 if(EASTL_UNLIKELY(position > (size_type)(x.mpEnd - x.mpBegin)))
1312 ThrowRangeException();
1315 return append(x.mpBegin + position, x.mpBegin + position +
eastl::min_alt(n, (size_type)(x.mpEnd - x.mpBegin) - position));
1319 template <
typename T,
typename Allocator>
1320 inline basic_string<T, Allocator>& basic_string<T, Allocator>::append(
const value_type* p, size_type n)
1322 return append(p, p + n);
1326 template <
typename T,
typename Allocator>
1327 inline basic_string<T, Allocator>& basic_string<T, Allocator>::append(
const value_type* p)
1329 return append(p, p + CharStrlen(p));
1333 template <
typename T,
typename Allocator>
1334 basic_string<T, Allocator>& basic_string<T, Allocator>::append(size_type n, value_type c)
1336 const size_type s = (size_type)(mpEnd - mpBegin);
1338 #if EASTL_STRING_OPT_LENGTH_ERRORS
1339 if(EASTL_UNLIKELY((n > kMaxSize) || (s > (kMaxSize - n))))
1340 ThrowLengthException();
1343 const size_type nCapacity = (size_type)((mpCapacity - mpBegin) - 1);
1345 if((s + n) > nCapacity)
1346 reserve(
eastl::max_alt((size_type)GetNewCapacity(nCapacity), (size_type)(s + n)));
1350 CharStringUninitializedFillN(mpEnd + 1, n - 1, c);
1360 template <
typename T,
typename Allocator>
1361 basic_string<T, Allocator>& basic_string<T, Allocator>::append(
const value_type* pBegin,
const value_type* pEnd)
1365 const size_type nOldSize = (size_type)(mpEnd - mpBegin);
1366 const size_type n = (size_type)(pEnd - pBegin);
1368 #if EASTL_STRING_OPT_LENGTH_ERRORS
1369 if(EASTL_UNLIKELY(((
size_t)n > kMaxSize) || (nOldSize > (kMaxSize - n))))
1370 ThrowLengthException();
1373 const size_type nCapacity = (size_type)((mpCapacity - mpBegin) - 1);
1375 if((nOldSize + n) > nCapacity)
1377 const size_type nLength =
eastl::max_alt((size_type)GetNewCapacity(nCapacity), (size_type)(nOldSize + n)) + 1;
1379 pointer pNewBegin = DoAllocate(nLength);
1380 pointer pNewEnd = pNewBegin;
1382 pNewEnd = CharStringUninitializedCopy(mpBegin, mpEnd, pNewBegin);
1383 pNewEnd = CharStringUninitializedCopy(pBegin, pEnd, pNewEnd);
1387 mpBegin = pNewBegin;
1389 mpCapacity = pNewBegin + nLength;
1393 const value_type* pTemp = pBegin;
1395 CharStringUninitializedCopy(pTemp, pEnd, mpEnd + 1);
1406 template <
typename T,
typename Allocator>
1407 basic_string<T, Allocator>& basic_string<T, Allocator>::append_sprintf_va_list(
const value_type* pFormat, va_list arguments)
1421 size_type nInitialSize = (size_type)(mpEnd - mpBegin);
1424 #if EASTL_VA_COPY_ENABLED
1425 va_list argumentsSaved;
1426 va_copy(argumentsSaved, arguments);
1429 if(mpBegin == GetEmptyString(value_type()))
1430 nReturnValue = eastl::Vsnprintf(mpEnd, 0, pFormat, arguments);
1432 nReturnValue = eastl::Vsnprintf(mpEnd, (
size_t)(mpCapacity - mpEnd), pFormat, arguments);
1434 if(nReturnValue >= (
int)(mpCapacity - mpEnd))
1437 #if EASTL_VA_COPY_ENABLED
1438 va_copy(arguments, argumentsSaved);
1440 resize(nInitialSize + nReturnValue);
1441 nReturnValue = eastl::Vsnprintf(mpBegin + nInitialSize, (
size_t)(nReturnValue + 1), pFormat, arguments);
1443 else if(nReturnValue < 0)
1446 size_type n =
eastl::max_alt((size_type)(EASTL_STRING_INITIAL_CAPACITY - 1), (size_type)(size() * 2));
1448 for(; (nReturnValue < 0) && (n < 1000000); n *= 2)
1450 #if EASTL_VA_COPY_ENABLED
1451 va_copy(arguments, argumentsSaved);
1455 const size_t nCapacity = (size_t)((n + 1) - nInitialSize);
1456 nReturnValue = eastl::Vsnprintf(mpBegin + nInitialSize, nCapacity, pFormat, arguments);
1458 if(nReturnValue == (
int)(
unsigned)nCapacity)
1461 nReturnValue = eastl::Vsnprintf(mpBegin + nInitialSize, nCapacity + 1, pFormat, arguments);
1466 if(nReturnValue >= 0)
1467 mpEnd = mpBegin + nInitialSize + nReturnValue;
1472 template <
typename T,
typename Allocator>
1473 basic_string<T, Allocator>& basic_string<T, Allocator>::append_sprintf(
const value_type* pFormat, ...)
1476 va_start(arguments, pFormat);
1477 append_sprintf_va_list(pFormat, arguments);
1484 template <
typename T,
typename Allocator>
1485 inline void basic_string<T, Allocator>::push_back(value_type c)
1487 if((mpEnd + 1) == mpCapacity)
1488 reserve(
eastl::max_alt(GetNewCapacity((size_type)((mpCapacity - mpBegin) - 1)), (size_type)(mpEnd - mpBegin) + 1));
1494 template <
typename T,
typename Allocator>
1495 inline void basic_string<T, Allocator>::pop_back()
1497 #if EASTL_ASSERT_ENABLED
1498 if(EASTL_UNLIKELY(mpEnd <= mpBegin))
1499 EASTL_FAIL_MSG(
"basic_string::pop_back -- empty string");
1502 mpEnd[-1] = value_type(0);
1507 template <
typename T,
typename Allocator>
1508 inline basic_string<T, Allocator>& basic_string<T, Allocator>::assign(
const basic_string<T, Allocator>& x)
1510 return assign(x.mpBegin, x.mpEnd);
1514 template <
typename T,
typename Allocator>
1515 inline basic_string<T, Allocator>& basic_string<T, Allocator>::assign(
const basic_string<T, Allocator>& x, size_type position, size_type n)
1517 #if EASTL_STRING_OPT_RANGE_ERRORS
1518 if(EASTL_UNLIKELY(position > (size_type)(x.mpEnd - x.mpBegin)))
1519 ThrowRangeException();
1522 return assign(x.mpBegin + position, x.mpBegin + position +
eastl::min_alt(n, (size_type)(x.mpEnd - x.mpBegin) - position));
1526 template <
typename T,
typename Allocator>
1527 inline basic_string<T, Allocator>& basic_string<T, Allocator>::assign(
const value_type* p, size_type n)
1529 return assign(p, p + n);
1533 template <
typename T,
typename Allocator>
1534 inline basic_string<T, Allocator>& basic_string<T, Allocator>::assign(
const value_type* p)
1536 return assign(p, p + CharStrlen(p));
1540 template <
typename T,
typename Allocator>
1541 basic_string<T, Allocator>& basic_string<T, Allocator>::assign(size_type n, value_type c)
1543 if(n <= (size_type)(mpEnd - mpBegin))
1545 CharTypeAssignN(mpBegin, n, c);
1546 erase(mpBegin + n, mpEnd);
1550 CharTypeAssignN(mpBegin, (size_type)(mpEnd - mpBegin), c);
1551 append(n - (size_type)(mpEnd - mpBegin), c);
1557 template <
typename T,
typename Allocator>
1558 basic_string<T, Allocator>& basic_string<T, Allocator>::assign(
const value_type* pBegin,
const value_type* pEnd)
1560 const ptrdiff_t n = pEnd - pBegin;
1561 if(static_cast<size_type>(n) <= (size_type)(mpEnd - mpBegin))
1563 memmove(mpBegin, pBegin, (
size_t)n *
sizeof(value_type));
1564 erase(mpBegin + n, mpEnd);
1568 memmove(mpBegin, pBegin, (
size_t)(mpEnd - mpBegin) *
sizeof(value_type));
1569 append(pBegin + (size_type)(mpEnd - mpBegin), pEnd);
1575 template <
typename T,
typename Allocator>
1576 basic_string<T, Allocator>& basic_string<T, Allocator>::insert(size_type position,
const basic_string<T, Allocator>& x)
1578 #if EASTL_STRING_OPT_RANGE_ERRORS
1579 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1580 ThrowRangeException();
1583 #if EASTL_STRING_OPT_LENGTH_ERRORS
1584 if(EASTL_UNLIKELY((size_type)(mpEnd - mpBegin) > (kMaxSize - (size_type)(x.mpEnd - x.mpBegin))))
1585 ThrowLengthException();
1588 insert(mpBegin + position, x.mpBegin, x.mpEnd);
1593 template <
typename T,
typename Allocator>
1594 basic_string<T, Allocator>& basic_string<T, Allocator>::insert(size_type position,
const basic_string<T, Allocator>& x, size_type beg, size_type n)
1596 #if EASTL_STRING_OPT_RANGE_ERRORS
1597 if(EASTL_UNLIKELY((position > (size_type)(mpEnd - mpBegin)) || (beg > (size_type)(x.mpEnd - x.mpBegin))))
1598 ThrowRangeException();
1601 size_type nLength =
eastl::min_alt(n, (size_type)(x.mpEnd - x.mpBegin) - beg);
1603 #if EASTL_STRING_OPT_LENGTH_ERRORS
1604 if(EASTL_UNLIKELY((size_type)(mpEnd - mpBegin) > (kMaxSize - nLength)))
1605 ThrowLengthException();
1608 insert(mpBegin + position, x.mpBegin + beg, x.mpBegin + beg + nLength);
1613 template <
typename T,
typename Allocator>
1614 basic_string<T, Allocator>& basic_string<T, Allocator>::insert(size_type position,
const value_type* p, size_type n)
1616 #if EASTL_STRING_OPT_RANGE_ERRORS
1617 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1618 ThrowRangeException();
1621 #if EASTL_STRING_OPT_LENGTH_ERRORS
1622 if(EASTL_UNLIKELY((size_type)(mpEnd - mpBegin) > (kMaxSize - n)))
1623 ThrowLengthException();
1626 insert(mpBegin + position, p, p + n);
1631 template <
typename T,
typename Allocator>
1632 basic_string<T, Allocator>& basic_string<T, Allocator>::insert(size_type position,
const value_type* p)
1634 #if EASTL_STRING_OPT_RANGE_ERRORS
1635 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1636 ThrowRangeException();
1639 size_type nLength = (size_type)CharStrlen(p);
1641 #if EASTL_STRING_OPT_LENGTH_ERRORS
1642 if(EASTL_UNLIKELY((size_type)(mpEnd - mpBegin) > (kMaxSize - nLength)))
1643 ThrowLengthException();
1646 insert(mpBegin + position, p, p + nLength);
1651 template <
typename T,
typename Allocator>
1652 basic_string<T, Allocator>& basic_string<T, Allocator>::insert(size_type position, size_type n, value_type c)
1654 #if EASTL_STRING_OPT_RANGE_ERRORS
1655 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1656 ThrowRangeException();
1659 #if EASTL_STRING_OPT_LENGTH_ERRORS
1660 if(EASTL_UNLIKELY((size_type)(mpEnd - mpBegin) > (kMaxSize - n)))
1661 ThrowLengthException();
1664 insert(mpBegin + position, n, c);
1669 template <
typename T,
typename Allocator>
1670 inline typename basic_string<T, Allocator>::iterator
1671 basic_string<T, Allocator>::insert(iterator p, value_type c)
1678 return InsertInternal(p, c);
1682 template <
typename T,
typename Allocator>
1683 void basic_string<T, Allocator>::insert(iterator p, size_type n, value_type c)
1685 #if EASTL_ASSERT_ENABLED
1686 if(EASTL_UNLIKELY((p < mpBegin) || (p > mpEnd)))
1687 EASTL_FAIL_MSG(
"basic_string::insert -- invalid position");
1692 if(size_type(mpCapacity - mpEnd) >= (n + 1))
1694 const size_type nElementsAfter = (size_type)(mpEnd - p);
1695 iterator pOldEnd = mpEnd;
1697 if(nElementsAfter >= n)
1699 CharStringUninitializedCopy((mpEnd - n) + 1, mpEnd + 1, mpEnd + 1);
1701 memmove(p + n, p, (
size_t)((nElementsAfter - n) + 1) *
sizeof(value_type));
1702 CharTypeAssignN(p, n, c);
1706 CharStringUninitializedFillN(mpEnd + 1, n - nElementsAfter - 1, c);
1707 mpEnd += n - nElementsAfter;
1709 #if EASTL_EXCEPTIONS_ENABLED
1713 CharStringUninitializedCopy(p, pOldEnd + 1, mpEnd);
1714 mpEnd += nElementsAfter;
1715 #if EASTL_EXCEPTIONS_ENABLED
1724 CharTypeAssignN(p, nElementsAfter + 1, c);
1729 const size_type nOldSize = (size_type)(mpEnd - mpBegin);
1730 const size_type nOldCap = (size_type)((mpCapacity - mpBegin) - 1);
1731 const size_type nLength =
eastl::max_alt((size_type)GetNewCapacity(nOldCap), (size_type)(nOldSize + n)) + 1;
1733 iterator pNewBegin = DoAllocate(nLength);
1734 iterator pNewEnd = pNewBegin;
1736 pNewEnd = CharStringUninitializedCopy(mpBegin, p, pNewBegin);
1737 pNewEnd = CharStringUninitializedFillN(pNewEnd, n, c);
1738 pNewEnd = CharStringUninitializedCopy(p, mpEnd, pNewEnd);
1742 mpBegin = pNewBegin;
1744 mpCapacity = pNewBegin + nLength;
1750 template <
typename T,
typename Allocator>
1751 void basic_string<T, Allocator>::insert(iterator p,
const value_type* pBegin,
const value_type* pEnd)
1753 #if EASTL_ASSERT_ENABLED
1754 if(EASTL_UNLIKELY((p < mpBegin) || (p > mpEnd)))
1755 EASTL_FAIL_MSG(
"basic_string::insert -- invalid position");
1758 const size_type n = (size_type)(pEnd - pBegin);
1762 const bool bCapacityIsSufficient = ((mpCapacity - mpEnd) >= (difference_type)(n + 1));
1763 const bool bSourceIsFromSelf = ((pEnd >= mpBegin) && (pBegin <= mpEnd));
1770 if(bCapacityIsSufficient && !bSourceIsFromSelf)
1772 const ptrdiff_t nElementsAfter = (mpEnd - p);
1773 iterator pOldEnd = mpEnd;
1775 if(nElementsAfter >= (ptrdiff_t)n)
1777 memmove(mpEnd + 1, mpEnd - n + 1, (
size_t)n *
sizeof(value_type));
1779 memmove(p + n, p, (
size_t)((nElementsAfter - n) + 1) *
sizeof(value_type));
1780 memmove(p, pBegin, (
size_t)(pEnd - pBegin) *
sizeof(value_type));
1784 const value_type*
const pMid = pBegin + (nElementsAfter + 1);
1786 memmove(mpEnd + 1, pMid, (
size_t)(pEnd - pMid) *
sizeof(value_type));
1787 mpEnd += n - nElementsAfter;
1789 #if EASTL_EXCEPTIONS_ENABLED
1793 memmove(mpEnd, p, (
size_t)(pOldEnd - p + 1) *
sizeof(value_type));
1794 mpEnd += nElementsAfter;
1795 #if EASTL_EXCEPTIONS_ENABLED
1804 memmove(p, pBegin, (
size_t)(pMid - pBegin) *
sizeof(value_type));
1809 const size_type nOldSize = (size_type)(mpEnd - mpBegin);
1810 const size_type nOldCap = (size_type)((mpCapacity - mpBegin) - 1);
1813 if(bCapacityIsSufficient)
1814 nLength = nOldSize + n + 1;
1816 nLength =
eastl::max_alt((size_type)GetNewCapacity(nOldCap), (size_type)(nOldSize + n)) + 1;
1818 pointer pNewBegin = DoAllocate(nLength);
1819 pointer pNewEnd = pNewBegin;
1821 pNewEnd = CharStringUninitializedCopy(mpBegin, p, pNewBegin);
1822 pNewEnd = CharStringUninitializedCopy(pBegin, pEnd, pNewEnd);
1823 pNewEnd = CharStringUninitializedCopy(p, mpEnd, pNewEnd);
1827 mpBegin = pNewBegin;
1829 mpCapacity = pNewBegin + nLength;
1835 template <
typename T,
typename Allocator>
1836 inline basic_string<T, Allocator>& basic_string<T, Allocator>::erase(size_type position, size_type n)
1838 #if EASTL_STRING_OPT_RANGE_ERRORS
1839 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1840 ThrowRangeException();
1843 #if EASTL_ASSERT_ENABLED
1844 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1845 EASTL_FAIL_MSG(
"basic_string::erase -- invalid position");
1848 erase(mpBegin + position, mpBegin + position +
eastl::min_alt(n, (size_type)(mpEnd - mpBegin) - position));
1853 template <
typename T,
typename Allocator>
1854 inline typename basic_string<T, Allocator>::iterator
1855 basic_string<T, Allocator>::erase(iterator p)
1857 #if EASTL_ASSERT_ENABLED
1858 if(EASTL_UNLIKELY((p < mpBegin) || (p >= mpEnd)))
1859 EASTL_FAIL_MSG(
"basic_string::erase -- invalid position");
1862 memmove(p, p + 1, (
size_t)(mpEnd - p) *
sizeof(value_type));
1868 template <
typename T,
typename Allocator>
1869 typename basic_string<T, Allocator>::iterator
1870 basic_string<T, Allocator>::erase(iterator pBegin, iterator pEnd)
1872 #if EASTL_ASSERT_ENABLED
1873 if(EASTL_UNLIKELY((pBegin < mpBegin) || (pBegin > mpEnd) || (pEnd < mpBegin) || (pEnd > mpEnd) || (pEnd < pBegin)))
1874 EASTL_FAIL_MSG(
"basic_string::erase -- invalid position");
1879 memmove(pBegin, pEnd, (
size_t)((mpEnd - pEnd) + 1) *
sizeof(value_type));
1880 const iterator pNewEnd = (mpEnd - (pEnd - pBegin));
1887 template <
typename T,
typename Allocator>
1888 inline typename basic_string<T, Allocator>::reverse_iterator
1889 basic_string<T, Allocator>::erase(reverse_iterator position)
1891 return reverse_iterator(erase((++position).base()));
1895 template <
typename T,
typename Allocator>
1896 typename basic_string<T, Allocator>::reverse_iterator
1897 basic_string<T, Allocator>::erase(reverse_iterator first, reverse_iterator last)
1899 return reverse_iterator(erase((++last).base(), (++first).base()));
1903 template <
typename T,
typename Allocator>
1904 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(size_type position, size_type n,
const basic_string<T, Allocator>& x)
1906 #if EASTL_STRING_OPT_RANGE_ERRORS
1907 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1908 ThrowRangeException();
1911 const size_type nLength =
eastl::min_alt(n, (size_type)(mpEnd - mpBegin) - position);
1913 #if EASTL_STRING_OPT_LENGTH_ERRORS
1914 if(EASTL_UNLIKELY(((size_type)(mpEnd - mpBegin) - nLength) >= (kMaxSize - (size_type)(x.mpEnd - x.mpBegin))))
1915 ThrowLengthException();
1918 return replace(mpBegin + position, mpBegin + position + nLength, x.mpBegin, x.mpEnd);
1922 template <
typename T,
typename Allocator>
1923 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(size_type pos1, size_type n1,
const basic_string<T, Allocator>& x, size_type pos2, size_type n2)
1925 #if EASTL_STRING_OPT_RANGE_ERRORS
1926 if(EASTL_UNLIKELY((pos1 > (size_type)(mpEnd - mpBegin)) || (pos2 > (size_type)(x.mpEnd - x.mpBegin))))
1927 ThrowRangeException();
1930 const size_type nLength1 =
eastl::min_alt(n1, (size_type)( mpEnd - mpBegin) - pos1);
1931 const size_type nLength2 =
eastl::min_alt(n2, (size_type)(x.mpEnd - x.mpBegin) - pos2);
1933 #if EASTL_STRING_OPT_LENGTH_ERRORS
1934 if(EASTL_UNLIKELY(((size_type)(mpEnd - mpBegin) - nLength1) >= (kMaxSize - nLength2)))
1935 ThrowLengthException();
1938 return replace(mpBegin + pos1, mpBegin + pos1 + nLength1, x.mpBegin + pos2, x.mpBegin + pos2 + nLength2);
1942 template <
typename T,
typename Allocator>
1943 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(size_type position, size_type n1,
const value_type* p, size_type n2)
1945 #if EASTL_STRING_OPT_RANGE_ERRORS
1946 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1947 ThrowRangeException();
1950 const size_type nLength =
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - position);
1952 #if EASTL_STRING_OPT_LENGTH_ERRORS
1953 if(EASTL_UNLIKELY((n2 > kMaxSize) || (((size_type)(mpEnd - mpBegin) - nLength) >= (kMaxSize - n2))))
1954 ThrowLengthException();
1957 return replace(mpBegin + position, mpBegin + position + nLength, p, p + n2);
1961 template <
typename T,
typename Allocator>
1962 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(size_type position, size_type n1,
const value_type* p)
1964 #if EASTL_STRING_OPT_RANGE_ERRORS
1965 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1966 ThrowRangeException();
1969 const size_type nLength =
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - position);
1971 #if EASTL_STRING_OPT_LENGTH_ERRORS
1972 const size_type n2 = (size_type)CharStrlen(p);
1973 if(EASTL_UNLIKELY((n2 > kMaxSize) || (((size_type)(mpEnd - mpBegin) - nLength) >= (kMaxSize - n2))))
1974 ThrowLengthException();
1977 return replace(mpBegin + position, mpBegin + position + nLength, p, p + CharStrlen(p));
1981 template <
typename T,
typename Allocator>
1982 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(size_type position, size_type n1, size_type n2, value_type c)
1984 #if EASTL_STRING_OPT_RANGE_ERRORS
1985 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
1986 ThrowRangeException();
1989 const size_type nLength =
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - position);
1991 #if EASTL_STRING_OPT_LENGTH_ERRORS
1992 if(EASTL_UNLIKELY((n2 > kMaxSize) || ((size_type)(mpEnd - mpBegin) - nLength) >= (kMaxSize - n2)))
1993 ThrowLengthException();
1996 return replace(mpBegin + position, mpBegin + position + nLength, n2, c);
2000 template <
typename T,
typename Allocator>
2001 inline basic_string<T, Allocator>& basic_string<T, Allocator>::replace(iterator pBegin, iterator pEnd,
const basic_string<T, Allocator>& x)
2003 return replace(pBegin, pEnd, x.mpBegin, x.mpEnd);
2007 template <
typename T,
typename Allocator>
2008 inline basic_string<T, Allocator>& basic_string<T, Allocator>::replace(iterator pBegin, iterator pEnd,
const value_type* p, size_type n)
2010 return replace(pBegin, pEnd, p, p + n);
2014 template <
typename T,
typename Allocator>
2015 inline basic_string<T, Allocator>& basic_string<T, Allocator>::replace(iterator pBegin, iterator pEnd,
const value_type* p)
2017 return replace(pBegin, pEnd, p, p + CharStrlen(p));
2021 template <
typename T,
typename Allocator>
2022 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(iterator pBegin, iterator pEnd, size_type n, value_type c)
2024 #if EASTL_ASSERT_ENABLED
2025 if(EASTL_UNLIKELY((pBegin < mpBegin) || (pBegin > mpEnd) || (pEnd < mpBegin) || (pEnd > mpEnd) || (pEnd < pBegin)))
2026 EASTL_FAIL_MSG(
"basic_string::replace -- invalid position");
2029 const size_type nLength = static_cast<size_type>(pEnd - pBegin);
2033 CharTypeAssignN(pBegin, n, c);
2034 erase(pBegin + n, pEnd);
2038 CharTypeAssignN(pBegin, nLength, c);
2039 insert(pEnd, n - nLength, c);
2045 template <
typename T,
typename Allocator>
2046 basic_string<T, Allocator>& basic_string<T, Allocator>::replace(iterator pBegin1, iterator pEnd1,
const value_type* pBegin2,
const value_type* pEnd2)
2048 #if EASTL_ASSERT_ENABLED
2049 if(EASTL_UNLIKELY((pBegin1 < mpBegin) || (pBegin1 > mpEnd) || (pEnd1 < mpBegin) || (pEnd1 > mpEnd) || (pEnd1 < pBegin1)))
2050 EASTL_FAIL_MSG(
"basic_string::replace -- invalid position");
2053 const size_type nLength1 = (size_type)(pEnd1 - pBegin1);
2054 const size_type nLength2 = (size_type)(pEnd2 - pBegin2);
2056 if(nLength1 >= nLength2)
2058 if((pBegin2 > pEnd1) || (pEnd2 <= pBegin1))
2059 memcpy(pBegin1, pBegin2, (
size_t)(pEnd2 - pBegin2) *
sizeof(value_type));
2061 memmove(pBegin1, pBegin2, (
size_t)(pEnd2 - pBegin2) *
sizeof(value_type));
2062 erase(pBegin1 + nLength2, pEnd1);
2066 if((pBegin2 > pEnd1) || (pEnd2 <= pBegin1))
2068 const value_type*
const pMid2 = pBegin2 + nLength1;
2070 if((pEnd2 <= pBegin1) || (pBegin2 > pEnd1))
2071 memcpy(pBegin1, pBegin2, (
size_t)(pMid2 - pBegin2) *
sizeof(value_type));
2073 memmove(pBegin1, pBegin2, (
size_t)(pMid2 - pBegin2) *
sizeof(value_type));
2074 insert(pEnd1, pMid2, pEnd2);
2079 const size_type nOldSize = (size_type)(mpEnd - mpBegin);
2080 const size_type nOldCap = (size_type)((mpCapacity - mpBegin) - 1);
2081 const size_type nNewCapacity =
eastl::max_alt((size_type)GetNewCapacity(nOldCap), (size_type)(nOldSize + (nLength2 - nLength1))) + 1;
2083 pointer pNewBegin = DoAllocate(nNewCapacity);
2084 pointer pNewEnd = pNewBegin;
2086 pNewEnd = CharStringUninitializedCopy(mpBegin, pBegin1, pNewBegin);
2087 pNewEnd = CharStringUninitializedCopy(pBegin2, pEnd2, pNewEnd);
2088 pNewEnd = CharStringUninitializedCopy(pEnd1, mpEnd, pNewEnd);
2092 mpBegin = pNewBegin;
2094 mpCapacity = pNewBegin + nNewCapacity;
2101 template <
typename T,
typename Allocator>
2102 typename basic_string<T, Allocator>::size_type
2103 basic_string<T, Allocator>::copy(value_type* p, size_type n, size_type position)
const
2105 #if EASTL_STRING_OPT_RANGE_ERRORS
2106 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
2107 ThrowRangeException();
2113 const size_type nLength =
eastl::min_alt(n, (size_type)(mpEnd - mpBegin) - position);
2114 memmove(p, mpBegin + position, (
size_t)nLength *
sizeof(value_type));
2119 template <
typename T,
typename Allocator>
2120 void basic_string<T, Allocator>::swap(basic_string<T, Allocator>& x)
2122 if(mAllocator == x.mAllocator)
2131 const this_type temp(*
this);
2138 template <
typename T,
typename Allocator>
2139 inline typename basic_string<T, Allocator>::size_type
2140 basic_string<T, Allocator>::find(
const basic_string<T, Allocator>& x, size_type position)
const
2142 return find(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2146 template <
typename T,
typename Allocator>
2147 inline typename basic_string<T, Allocator>::size_type
2148 basic_string<T, Allocator>::find(
const value_type* p, size_type position)
const
2150 return find(p, position, (size_type)CharStrlen(p));
2154 #if defined(EA_PLATFORM_XENON) // If XBox 360...
2156 template <
typename T,
typename Allocator>
2157 typename basic_string<T, Allocator>::size_type
2158 basic_string<T, Allocator>::find(
const value_type* p, size_type position, size_type n)
const
2160 const size_type nLength = (size_type)(mpEnd - mpBegin);
2162 if(n || (position > nLength))
2164 if(position < nLength)
2166 size_type nRemain = nLength - position;
2172 for(
const value_type* p1, *p2 = mpBegin + position;
2173 (p1 = Find(p2, *p, nRemain)) != 0;
2174 nRemain -= (p1 - p2) + 1, p2 = (p1 + 1))
2176 if(Compare(p1, p, n) == 0)
2177 return (size_type)(p1 - mpBegin);
2188 template <
typename T,
typename Allocator>
2189 typename basic_string<T, Allocator>::size_type
2190 basic_string<T, Allocator>::find(
const value_type* p, size_type position, size_type n)
const
2199 if(EASTL_LIKELY((position + n) <= (size_type)(mpEnd - mpBegin)))
2201 const value_type*
const pTemp =
eastl::search(mpBegin + position, mpEnd, p, p + n);
2203 if((pTemp != mpEnd) || (n == 0))
2204 return (size_type)(pTemp - mpBegin);
2211 template <
typename T,
typename Allocator>
2212 typename basic_string<T, Allocator>::size_type
2213 basic_string<T, Allocator>::find(value_type c, size_type position)
const
2222 if(EASTL_LIKELY(position < (size_type)(mpEnd - mpBegin)))
2224 const const_iterator pResult =
eastl::find(mpBegin + position, mpEnd, c);
2226 if(pResult != mpEnd)
2227 return (size_type)(pResult - mpBegin);
2233 template <
typename T,
typename Allocator>
2234 inline typename basic_string<T, Allocator>::size_type
2235 basic_string<T, Allocator>::rfind(
const basic_string<T, Allocator>& x, size_type position)
const
2237 return rfind(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2241 template <
typename T,
typename Allocator>
2242 inline typename basic_string<T, Allocator>::size_type
2243 basic_string<T, Allocator>::rfind(
const value_type* p, size_type position)
const
2245 return rfind(p, position, (size_type)CharStrlen(p));
2249 template <
typename T,
typename Allocator>
2250 typename basic_string<T, Allocator>::size_type
2251 basic_string<T, Allocator>::rfind(
const value_type* p, size_type position, size_type n)
const
2266 const size_type nLength = (size_type)(mpEnd - mpBegin);
2268 if(EASTL_LIKELY(n <= nLength))
2272 const const_iterator pEnd = mpBegin +
eastl::min_alt(nLength - n, position) + n;
2273 const const_iterator pResult = CharTypeStringRSearch(mpBegin, pEnd, p, p + n);
2276 return (size_type)(pResult - mpBegin);
2285 template <
typename T,
typename Allocator>
2286 typename basic_string<T, Allocator>::size_type
2287 basic_string<T, Allocator>::rfind(value_type c, size_type position)
const
2290 const size_type nLength = (size_type)(mpEnd - mpBegin);
2292 if(EASTL_LIKELY(nLength))
2294 const value_type*
const pEnd = mpBegin +
eastl::min_alt(nLength - 1, position) + 1;
2295 const value_type*
const pResult = CharTypeStringRFind(pEnd, mpBegin, c);
2297 if(pResult != mpBegin)
2298 return (size_type)((pResult - 1) - mpBegin);
2304 template <
typename T,
typename Allocator>
2305 inline typename basic_string<T, Allocator>::size_type
2306 basic_string<T, Allocator>::find_first_of(
const basic_string<T, Allocator>& x, size_type position)
const
2308 return find_first_of(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2312 template <
typename T,
typename Allocator>
2313 inline typename basic_string<T, Allocator>::size_type
2314 basic_string<T, Allocator>::find_first_of(
const value_type* p, size_type position)
const
2316 return find_first_of(p, position, (size_type)CharStrlen(p));
2320 #if defined(EA_PLATFORM_XENON) // If XBox 360...
2322 template <
typename T,
typename Allocator>
2323 typename basic_string<T, Allocator>::size_type
2324 basic_string<T, Allocator>::find_first_of(
const value_type* p, size_type position, size_type n)
const
2327 if(n && (position < (size_type)(mpEnd - mpBegin)))
2329 for(
const value_type* p1 = (mpBegin + position); p1 < mpEnd; ++p1)
2331 if(Find(p, *p1, n) != 0)
2332 return (size_type)(p1 - mpBegin);
2338 template <
typename T,
typename Allocator>
2339 typename basic_string<T, Allocator>::size_type
2340 basic_string<T, Allocator>::find_first_of(
const value_type* p, size_type position, size_type n)
const
2343 if(EASTL_LIKELY((position < (size_type)(mpEnd - mpBegin))))
2345 const value_type*
const pBegin = mpBegin + position;
2346 const const_iterator pResult = CharTypeStringFindFirstOf(pBegin, mpEnd, p, p + n);
2348 if(pResult != mpEnd)
2349 return (size_type)(pResult - mpBegin);
2356 template <
typename T,
typename Allocator>
2357 inline typename basic_string<T, Allocator>::size_type
2358 basic_string<T, Allocator>::find_first_of(value_type c, size_type position)
const
2360 return find(c, position);
2364 template <
typename T,
typename Allocator>
2365 inline typename basic_string<T, Allocator>::size_type
2366 basic_string<T, Allocator>::find_last_of(
const basic_string<T, Allocator>& x, size_type position)
const
2368 return find_last_of(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2372 template <
typename T,
typename Allocator>
2373 inline typename basic_string<T, Allocator>::size_type
2374 basic_string<T, Allocator>::find_last_of(
const value_type* p, size_type position)
const
2376 return find_last_of(p, position, (size_type)CharStrlen(p));
2380 #if defined(EA_PLATFORM_XENON) // If XBox 360...
2382 template <
typename T,
typename Allocator>
2383 typename basic_string<T, Allocator>::size_type
2384 basic_string<T, Allocator>::find_last_of(
const value_type* p, size_type position, size_type n)
const
2387 const size_type nLength = (size_type)(mpEnd - mpBegin);
2391 const value_type* p1;
2393 if(position < nLength)
2394 p1 = mpBegin + position;
2401 return (size_type)(p1 - mpBegin);
2411 template <
typename T,
typename Allocator>
2412 typename basic_string<T, Allocator>::size_type
2413 basic_string<T, Allocator>::find_last_of(
const value_type* p, size_type position, size_type n)
const
2416 const size_type nLength = (size_type)(mpEnd - mpBegin);
2418 if(EASTL_LIKELY(nLength))
2420 const value_type*
const pEnd = mpBegin +
eastl::min_alt(nLength - 1, position) + 1;
2421 const value_type*
const pResult = CharTypeStringRFindFirstOf(pEnd, mpBegin, p, p + n);
2423 if(pResult != mpBegin)
2424 return (size_type)((pResult - 1) - mpBegin);
2431 template <
typename T,
typename Allocator>
2432 inline typename basic_string<T, Allocator>::size_type
2433 basic_string<T, Allocator>::find_last_of(value_type c, size_type position)
const
2435 return rfind(c, position);
2439 template <
typename T,
typename Allocator>
2440 inline typename basic_string<T, Allocator>::size_type
2441 basic_string<T, Allocator>::find_first_not_of(
const basic_string<T, Allocator>& x, size_type position)
const
2443 return find_first_not_of(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2447 template <
typename T,
typename Allocator>
2448 inline typename basic_string<T, Allocator>::size_type
2449 basic_string<T, Allocator>::find_first_not_of(
const value_type* p, size_type position)
const
2455 template <
typename T,
typename Allocator>
2456 typename basic_string<T, Allocator>::size_type
2457 basic_string<T, Allocator>::find_first_not_of(
const value_type* p, size_type position, size_type n)
const
2459 if(EASTL_LIKELY(position <= (size_type)(mpEnd - mpBegin)))
2461 const const_iterator pResult = CharTypeStringFindFirstNotOf(mpBegin + position, mpEnd, p, p + n);
2463 if(pResult != mpEnd)
2464 return (size_type)(pResult - mpBegin);
2470 template <
typename T,
typename Allocator>
2471 typename basic_string<T, Allocator>::size_type
2472 basic_string<T, Allocator>::find_first_not_of(value_type c, size_type position)
const
2474 if(EASTL_LIKELY(position <= (size_type)(mpEnd - mpBegin)))
2477 const const_iterator pResult = CharTypeStringFindFirstNotOf(mpBegin + position, mpEnd, &c, &c + 1);
2479 if(pResult != mpEnd)
2480 return (size_type)(pResult - mpBegin);
2486 template <
typename T,
typename Allocator>
2487 inline typename basic_string<T, Allocator>::size_type
2488 basic_string<T, Allocator>::find_last_not_of(
const basic_string<T, Allocator>& x, size_type position)
const
2490 return find_last_not_of(x.mpBegin, position, (size_type)(x.mpEnd - x.mpBegin));
2494 template <
typename T,
typename Allocator>
2495 inline typename basic_string<T, Allocator>::size_type
2496 basic_string<T, Allocator>::find_last_not_of(
const value_type* p, size_type position)
const
2498 return find_last_not_of(p, position, (size_type)CharStrlen(p));
2502 template <
typename T,
typename Allocator>
2503 typename basic_string<T, Allocator>::size_type
2504 basic_string<T, Allocator>::find_last_not_of(
const value_type* p, size_type position, size_type n)
const
2506 const size_type nLength = (size_type)(mpEnd - mpBegin);
2508 if(EASTL_LIKELY(nLength))
2510 const value_type*
const pEnd = mpBegin +
eastl::min_alt(nLength - 1, position) + 1;
2511 const value_type*
const pResult = CharTypeStringRFindFirstNotOf(pEnd, mpBegin, p, p + n);
2513 if(pResult != mpBegin)
2514 return (size_type)((pResult - 1) - mpBegin);
2520 template <
typename T,
typename Allocator>
2521 typename basic_string<T, Allocator>::size_type
2522 basic_string<T, Allocator>::find_last_not_of(value_type c, size_type position)
const
2524 const size_type nLength = (size_type)(mpEnd - mpBegin);
2526 if(EASTL_LIKELY(nLength))
2529 const value_type*
const pEnd = mpBegin +
eastl::min_alt(nLength - 1, position) + 1;
2530 const value_type*
const pResult = CharTypeStringRFindFirstNotOf(pEnd, mpBegin, &c, &c + 1);
2532 if(pResult != mpBegin)
2533 return (size_type)((pResult - 1) - mpBegin);
2539 template <
typename T,
typename Allocator>
2540 inline basic_string<T, Allocator> basic_string<T, Allocator>::substr(size_type position, size_type n)
const
2542 #if EASTL_STRING_OPT_RANGE_ERRORS
2543 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
2544 ThrowRangeException();
2545 #elif EASTL_ASSERT_ENABLED
2546 if(EASTL_UNLIKELY(position > (size_type)(mpEnd - mpBegin)))
2547 EASTL_FAIL_MSG(
"basic_string::substr -- invalid position");
2550 return basic_string(mpBegin + position, mpBegin + position +
eastl::min_alt(n, (size_type)(mpEnd - mpBegin) - position), mAllocator);
2554 template <
typename T,
typename Allocator>
2555 inline int basic_string<T, Allocator>::compare(
const basic_string<T, Allocator>& x)
const
2557 return compare(mpBegin, mpEnd, x.mpBegin, x.mpEnd);
2561 template <
typename T,
typename Allocator>
2562 inline int basic_string<T, Allocator>::compare(size_type pos1, size_type n1,
const basic_string<T, Allocator>& x)
const
2564 #if EASTL_STRING_OPT_RANGE_ERRORS
2565 if(EASTL_UNLIKELY(pos1 > (size_type)(mpEnd - mpBegin)))
2566 ThrowRangeException();
2569 return compare(mpBegin + pos1,
2570 mpBegin + pos1 +
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - pos1),
2576 template <
typename T,
typename Allocator>
2577 inline int basic_string<T, Allocator>::compare(size_type pos1, size_type n1,
const basic_string<T, Allocator>& x, size_type pos2, size_type n2)
const
2579 #if EASTL_STRING_OPT_RANGE_ERRORS
2580 if(EASTL_UNLIKELY((pos1 > (size_type)(mpEnd - mpBegin)) || (pos2 > (size_type)(x.mpEnd - x.mpBegin))))
2581 ThrowRangeException();
2584 return compare(mpBegin + pos1,
2585 mpBegin + pos1 +
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - pos1),
2587 x.mpBegin + pos2 +
eastl::min_alt(n2, (size_type)(mpEnd - mpBegin) - pos2));
2591 template <
typename T,
typename Allocator>
2592 inline int basic_string<T, Allocator>::compare(
const value_type* p)
const
2594 return compare(mpBegin, mpEnd, p, p + CharStrlen(p));
2598 template <
typename T,
typename Allocator>
2599 inline int basic_string<T, Allocator>::compare(size_type pos1, size_type n1,
const value_type* p)
const
2601 #if EASTL_STRING_OPT_RANGE_ERRORS
2602 if(EASTL_UNLIKELY(pos1 > (size_type)(mpEnd - mpBegin)))
2603 ThrowRangeException();
2606 return compare(mpBegin + pos1,
2607 mpBegin + pos1 +
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - pos1),
2613 template <
typename T,
typename Allocator>
2614 inline int basic_string<T, Allocator>::compare(size_type pos1, size_type n1,
const value_type* p, size_type n2)
const
2616 #if EASTL_STRING_OPT_RANGE_ERRORS
2617 if(EASTL_UNLIKELY(pos1 > (size_type)(mpEnd - mpBegin)))
2618 ThrowRangeException();
2621 return compare(mpBegin + pos1,
2622 mpBegin + pos1 +
eastl::min_alt(n1, (size_type)(mpEnd - mpBegin) - pos1),
2631 template <
typename T,
typename Allocator>
2632 inline void basic_string<T, Allocator>::make_lower()
2634 for(pointer p = mpBegin; p < mpEnd; ++p)
2635 *p = (value_type)CharToLower(*p);
2642 template <
typename T,
typename Allocator>
2643 inline void basic_string<T, Allocator>::make_upper()
2645 for(pointer p = mpBegin; p < mpEnd; ++p)
2646 *p = (value_type)CharToUpper(*p);
2650 template <
typename T,
typename Allocator>
2651 inline void basic_string<T, Allocator>::ltrim()
2653 const value_type array[] = {
' ',
'\t', 0 };
2658 template <
typename T,
typename Allocator>
2659 inline void basic_string<T, Allocator>::rtrim()
2661 const value_type array[] = {
' ',
'\t', 0 };
2662 erase(find_last_not_of(array) + 1);
2666 template <
typename T,
typename Allocator>
2667 inline void basic_string<T, Allocator>::trim()
2674 template <
typename T,
typename Allocator>
2675 inline basic_string<T, Allocator> basic_string<T, Allocator>::left(size_type n)
const
2677 const size_type nLength = length();
2679 return substr(0, n);
2684 template <
typename T,
typename Allocator>
2685 inline basic_string<T, Allocator> basic_string<T, Allocator>::right(size_type n)
const
2687 const size_type nLength = length();
2689 return substr(nLength - n, n);
2694 template <
typename T,
typename Allocator>
2695 inline basic_string<T, Allocator>& basic_string<T, Allocator>::sprintf(
const value_type* pFormat, ...)
2698 va_start(arguments, pFormat);
2700 append_sprintf_va_list(pFormat, arguments);
2707 template <
typename T,
typename Allocator>
2708 basic_string<T, Allocator>& basic_string<T, Allocator>::sprintf_va_list(
const value_type* pFormat, va_list arguments)
2712 return append_sprintf_va_list(pFormat, arguments);
2716 template <
typename T,
typename Allocator>
2717 int basic_string<T, Allocator>::compare(
const value_type* pBegin1,
const value_type* pEnd1,
2718 const value_type* pBegin2,
const value_type* pEnd2)
2720 const ptrdiff_t n1 = pEnd1 - pBegin1;
2721 const ptrdiff_t n2 = pEnd2 - pBegin2;
2723 const int cmp = Compare(pBegin1, pBegin2, (
size_t)nMin);
2725 return (cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)));
2729 template <
typename T,
typename Allocator>
2730 int basic_string<T, Allocator>::comparei(
const value_type* pBegin1,
const value_type* pEnd1,
2731 const value_type* pBegin2,
const value_type* pEnd2)
2733 const ptrdiff_t n1 = pEnd1 - pBegin1;
2734 const ptrdiff_t n2 = pEnd2 - pBegin2;
2736 const int cmp = CompareI(pBegin1, pBegin2, (
size_t)nMin);
2738 return (cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)));
2742 template <
typename T,
typename Allocator>
2743 inline int basic_string<T, Allocator>::comparei(
const basic_string<T, Allocator>& x)
const
2745 return comparei(mpBegin, mpEnd, x.mpBegin, x.mpEnd);
2749 template <
typename T,
typename Allocator>
2750 inline int basic_string<T, Allocator>::comparei(
const value_type* p)
const
2752 return comparei(mpBegin, mpEnd, p, p + CharStrlen(p));
2756 template <
typename T,
typename Allocator>
2757 typename basic_string<T, Allocator>::iterator
2758 basic_string<T, Allocator>::InsertInternal(iterator p, value_type c)
2760 iterator pNewPosition = p;
2762 if((mpEnd + 1) < mpCapacity)
2765 memmove(p + 1, p, (
size_t)(mpEnd - p) *
sizeof(value_type));
2771 const size_type nOldSize = (size_type)(mpEnd - mpBegin);
2772 const size_type nOldCap = (size_type)((mpCapacity - mpBegin) - 1);
2773 const size_type nLength =
eastl::max_alt((size_type)GetNewCapacity(nOldCap), (size_type)(nOldSize + 1)) + 1;
2775 iterator pNewBegin = DoAllocate(nLength);
2776 iterator pNewEnd = pNewBegin;
2778 pNewPosition = CharStringUninitializedCopy(mpBegin, p, pNewBegin);
2781 pNewEnd = pNewPosition + 1;
2782 pNewEnd = CharStringUninitializedCopy(p, mpEnd, pNewEnd);
2786 mpBegin = pNewBegin;
2788 mpCapacity = pNewBegin + nLength;
2790 return pNewPosition;
2794 template <
typename T,
typename Allocator>
2795 void basic_string<T, Allocator>::SizeInitialize(size_type n, value_type c)
2797 AllocateSelf((size_type)(n + 1));
2799 mpEnd = CharStringUninitializedFillN(mpBegin, n, c);
2804 template <
typename T,
typename Allocator>
2805 void basic_string<T, Allocator>::RangeInitialize(
const value_type* pBegin,
const value_type* pEnd)
2807 const size_type n = (size_type)(pEnd - pBegin);
2809 #if EASTL_STRING_OPT_ARGUMENT_ERRORS
2810 if(EASTL_UNLIKELY(!pBegin && (n != 0)))
2811 ThrowInvalidArgumentException();
2814 AllocateSelf((size_type)(n + 1));
2816 mpEnd = CharStringUninitializedCopy(pBegin, pEnd, mpBegin);
2821 template <
typename T,
typename Allocator>
2822 inline void basic_string<T, Allocator>::RangeInitialize(
const value_type* pBegin)
2824 #if EASTL_STRING_OPT_ARGUMENT_ERRORS
2825 if(EASTL_UNLIKELY(!pBegin))
2826 ThrowInvalidArgumentException();
2829 RangeInitialize(pBegin, pBegin + CharStrlen(pBegin));
2833 template <
typename T,
typename Allocator>
2834 inline typename basic_string<T, Allocator>::value_type*
2835 basic_string<T, Allocator>::DoAllocate(size_type n)
2837 EASTL_ASSERT(n > 1);
2838 return (value_type*)EASTLAlloc(mAllocator, n *
sizeof(value_type));
2842 template <
typename T,
typename Allocator>
2843 inline void basic_string<T, Allocator>::DoFree(value_type* p, size_type n)
2846 EASTLFree(mAllocator, p, n *
sizeof(value_type));
2850 template <
typename T,
typename Allocator>
2851 inline typename basic_string<T, Allocator>::size_type
2852 basic_string<T, Allocator>::GetNewCapacity(size_type currentCapacity)
2854 return (currentCapacity > EASTL_STRING_INITIAL_CAPACITY) ? (2 * currentCapacity) : EASTL_STRING_INITIAL_CAPACITY;
2858 template <
typename T,
typename Allocator>
2859 inline void basic_string<T, Allocator>::AllocateSelf()
2862 mpBegin = const_cast<value_type*>(GetEmptyString(value_type()));
2864 mpCapacity = mpBegin + 1;
2868 template <
typename T,
typename Allocator>
2869 void basic_string<T, Allocator>::AllocateSelf(size_type n)
2871 #if EASTL_ASSERT_ENABLED
2872 if(EASTL_UNLIKELY(n >= 0x40000000))
2873 EASTL_FAIL_MSG(
"basic_string::AllocateSelf -- improbably large request.");
2876 #if EASTL_STRING_OPT_LENGTH_ERRORS
2877 if(EASTL_UNLIKELY(n > kMaxSize))
2878 ThrowLengthException();
2883 mpBegin = DoAllocate(n);
2885 mpCapacity = mpBegin + n;
2892 template <
typename T,
typename Allocator>
2893 inline void basic_string<T, Allocator>::DeallocateSelf()
2899 if((mpCapacity - mpBegin) > 1)
2900 DoFree(mpBegin, (size_type)(mpCapacity - mpBegin));
2904 template <
typename T,
typename Allocator>
2905 inline void basic_string<T, Allocator>::ThrowLengthException()
const
2907 #if EASTL_EXCEPTIONS_ENABLED
2908 throw std::length_error(
"basic_string -- length_error");
2909 #elif EASTL_ASSERT_ENABLED
2910 EASTL_FAIL_MSG(
"basic_string -- length_error");
2915 template <
typename T,
typename Allocator>
2916 inline void basic_string<T, Allocator>::ThrowRangeException()
const
2918 #if EASTL_EXCEPTIONS_ENABLED
2919 throw std::out_of_range(
"basic_string -- out of range");
2920 #elif EASTL_ASSERT_ENABLED
2921 EASTL_FAIL_MSG(
"basic_string -- out of range");
2926 template <
typename T,
typename Allocator>
2927 inline void basic_string<T, Allocator>::ThrowInvalidArgumentException()
const
2929 #if EASTL_EXCEPTIONS_ENABLED
2930 throw std::invalid_argument(
"basic_string -- invalid argument");
2931 #elif EASTL_ASSERT_ENABLED
2932 EASTL_FAIL_MSG(
"basic_string -- invalid argument");
2940 template <
typename T,
typename Allocator>
2941 const typename basic_string<T, Allocator>::value_type*
2942 basic_string<T, Allocator>::CharTypeStringFindEnd(
const value_type* pBegin,
const value_type* pEnd, value_type c)
2944 const value_type* pTemp = pEnd;
2945 while(--pTemp >= pBegin)
2957 template <
typename T,
typename Allocator>
2958 const typename basic_string<T, Allocator>::value_type*
2959 basic_string<T, Allocator>::CharTypeStringRFind(
const value_type* pRBegin,
const value_type* pREnd,
const value_type c)
2961 while(pRBegin > pREnd)
2963 if(*(pRBegin - 1) == c)
2974 template <
typename T,
typename Allocator>
2975 const typename basic_string<T, Allocator>::value_type*
2976 basic_string<T, Allocator>::CharTypeStringSearch(
const value_type* p1Begin,
const value_type* p1End,
2977 const value_type* p2Begin,
const value_type* p2End)
2981 if((p1Begin == p1End) || (p2Begin == p2End))
2985 if((p2Begin + 1) == p2End)
2989 const value_type* pTemp;
2990 const value_type* pTemp1 = (p2Begin + 1);
2991 const value_type* pCurrent = p1Begin;
2993 while(p1Begin != p1End)
2996 if(p1Begin == p1End)
3001 if(++pCurrent == p1End)
3004 while(*pCurrent == *pTemp)
3006 if(++pTemp == p2End)
3008 if(++pCurrent == p1End)
3022 template <
typename T,
typename Allocator>
3023 const typename basic_string<T, Allocator>::value_type*
3024 basic_string<T, Allocator>::CharTypeStringRSearch(
const value_type* p1Begin,
const value_type* p1End,
3025 const value_type* p2Begin,
const value_type* p2End)
3029 if((p1Begin == p1End) || (p2Begin == p2End))
3033 if((p2Begin + 1) == p2End)
3034 return CharTypeStringFindEnd(p1Begin, p1End, *p2Begin);
3037 if((p2End - p2Begin) > (p1End - p1Begin))
3041 const value_type* pSearchEnd = (p1End - (p2End - p2Begin) + 1);
3042 const value_type* pCurrent1;
3043 const value_type* pCurrent2;
3045 while(pSearchEnd != p1Begin)
3048 pCurrent1 = CharTypeStringFindEnd(p1Begin, pSearchEnd, *p2Begin);
3049 if(pCurrent1 == pSearchEnd)
3053 pCurrent2 = p2Begin;
3054 while(*pCurrent1++ == *pCurrent2++)
3056 if(pCurrent2 == p2End)
3057 return (pCurrent1 - (p2End - p2Begin));
3072 template <
typename T,
typename Allocator>
3073 const typename basic_string<T, Allocator>::value_type*
3074 basic_string<T, Allocator>::CharTypeStringFindFirstOf(
const value_type* p1Begin,
const value_type* p1End,
3075 const value_type* p2Begin,
const value_type* p2End)
3077 for( ; p1Begin != p1End; ++p1Begin)
3079 for(
const value_type* pTemp = p2Begin; pTemp != p2End; ++pTemp)
3081 if(*p1Begin == *pTemp)
3092 template <
typename T,
typename Allocator>
3093 const typename basic_string<T, Allocator>::value_type*
3094 basic_string<T, Allocator>::CharTypeStringRFindFirstOf(
const value_type* p1RBegin,
const value_type* p1REnd,
3095 const value_type* p2Begin,
const value_type* p2End)
3097 for( ; p1RBegin != p1REnd; --p1RBegin)
3099 for(
const value_type* pTemp = p2Begin; pTemp != p2End; ++pTemp)
3101 if(*(p1RBegin - 1) == *pTemp)
3112 template <
typename T,
typename Allocator>
3113 const typename basic_string<T, Allocator>::value_type*
3114 basic_string<T, Allocator>::CharTypeStringFindFirstNotOf(
const value_type* p1Begin,
const value_type* p1End,
3115 const value_type* p2Begin,
const value_type* p2End)
3117 for( ; p1Begin != p1End; ++p1Begin)
3119 const value_type* pTemp;
3120 for(pTemp = p2Begin; pTemp != p2End; ++pTemp)
3122 if(*p1Begin == *pTemp)
3134 template <
typename T,
typename Allocator>
3135 const typename basic_string<T, Allocator>::value_type*
3136 basic_string<T, Allocator>::CharTypeStringRFindFirstNotOf(
const value_type* p1RBegin,
const value_type* p1REnd,
3137 const value_type* p2Begin,
const value_type* p2End)
3139 for( ; p1RBegin != p1REnd; --p1RBegin)
3141 const value_type* pTemp;
3142 for(pTemp = p2Begin; pTemp != p2End; ++pTemp)
3144 if(*(p1RBegin-1) == *pTemp)
3157 template <
typename T,
typename Allocator>
3158 inline bool operator==(
const typename basic_string<T, Allocator>::reverse_iterator& r1,
3159 const typename basic_string<T, Allocator>::reverse_iterator& r2)
3161 return r1.mpCurrent == r2.mpCurrent;
3165 template <
typename T,
typename Allocator>
3166 inline bool operator!=(
const typename basic_string<T, Allocator>::reverse_iterator& r1,
3167 const typename basic_string<T, Allocator>::reverse_iterator& r2)
3169 return r1.mpCurrent != r2.mpCurrent;
3174 template <
typename T,
typename Allocator>
3175 basic_string<T, Allocator> operator+(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3177 typedef typename basic_string<T, Allocator>::CtorDoNotInitialize CtorDoNotInitialize;
3178 CtorDoNotInitialize cDNI;
3179 basic_string<T, Allocator> result(cDNI, a.size() + b.size(),
const_cast<basic_string<T, Allocator>&
>(a).get_allocator());
3186 template <
typename T,
typename Allocator>
3187 basic_string<T, Allocator> operator+(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3189 typedef typename basic_string<T, Allocator>::CtorDoNotInitialize CtorDoNotInitialize;
3190 CtorDoNotInitialize cDNI;
3191 const typename basic_string<T, Allocator>::size_type n = (
typename basic_string<T, Allocator>::size_type)CharStrlen(p);
3192 basic_string<T, Allocator> result(cDNI, n + b.size(),
const_cast<basic_string<T, Allocator>&
>(b).get_allocator());
3193 result.append(p, p + n);
3199 template <
typename T,
typename Allocator>
3200 basic_string<T, Allocator> operator+(
typename basic_string<T, Allocator>::value_type c,
const basic_string<T, Allocator>& b)
3202 typedef typename basic_string<T, Allocator>::CtorDoNotInitialize CtorDoNotInitialize;
3203 CtorDoNotInitialize cDNI;
3204 basic_string<T, Allocator> result(cDNI, 1 + b.size(),
const_cast<basic_string<T, Allocator>&
>(b).get_allocator());
3205 result.push_back(c);
3211 template <
typename T,
typename Allocator>
3212 basic_string<T, Allocator> operator+(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3214 typedef typename basic_string<T, Allocator>::CtorDoNotInitialize CtorDoNotInitialize;
3215 CtorDoNotInitialize cDNI;
3216 const typename basic_string<T, Allocator>::size_type n = (
typename basic_string<T, Allocator>::size_type)CharStrlen(p);
3217 basic_string<T, Allocator> result(cDNI, a.size() + n,
const_cast<basic_string<T, Allocator>&
>(a).get_allocator());
3219 result.append(p, p + n);
3224 template <
typename T,
typename Allocator>
3225 basic_string<T, Allocator> operator+(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type c)
3227 typedef typename basic_string<T, Allocator>::CtorDoNotInitialize CtorDoNotInitialize;
3228 CtorDoNotInitialize cDNI;
3229 basic_string<T, Allocator> result(cDNI, a.size() + 1,
const_cast<basic_string<T, Allocator>&
>(a).get_allocator());
3231 result.push_back(c);
3236 template <
typename T,
typename Allocator>
3237 inline bool basic_string<T, Allocator>::validate()
const
3239 if((mpBegin == NULL) || (mpEnd == NULL))
3243 if(mpCapacity < mpEnd)
3249 template <
typename T,
typename Allocator>
3250 inline int basic_string<T, Allocator>::validate_iterator(const_iterator i)
const
3270 template <
typename T,
typename Allocator>
3271 inline bool operator==(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3273 return ((a.size() == b.size()) && (memcmp(a.data(), b.data(), (size_t)a.size() *
sizeof(
typename basic_string<T, Allocator>::value_type)) == 0));
3277 template <
typename T,
typename Allocator>
3278 inline bool operator==(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3280 typedef typename basic_string<T, Allocator>::size_type size_type;
3281 const size_type n = (size_type)CharStrlen(p);
3282 return ((n == b.size()) && (memcmp(p, b.data(), (size_t)n *
sizeof(*p)) == 0));
3286 template <
typename T,
typename Allocator>
3287 inline bool operator==(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3289 typedef typename basic_string<T, Allocator>::size_type size_type;
3290 const size_type n = (size_type)CharStrlen(p);
3291 return ((a.size() == n) && (memcmp(a.data(), p, (size_t)n *
sizeof(*p)) == 0));
3295 template <
typename T,
typename Allocator>
3296 inline bool operator!=(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3302 template <
typename T,
typename Allocator>
3303 inline bool operator!=(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3309 template <
typename T,
typename Allocator>
3310 inline bool operator!=(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3317 template <
typename T,
typename Allocator>
3318 inline bool operator<(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3320 return basic_string<T, Allocator>::compare(a.begin(), a.end(), b.begin(), b.end()) < 0; }
3323 template <
typename T,
typename Allocator>
3324 inline bool operator<(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3326 typedef typename basic_string<T, Allocator>::size_type size_type;
3327 const size_type n = (size_type)CharStrlen(p);
3328 return basic_string<T, Allocator>::compare(p, p + n, b.begin(), b.end()) < 0;
3332 template <
typename T,
typename Allocator>
3333 inline bool operator<(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3335 typedef typename basic_string<T, Allocator>::size_type size_type;
3336 const size_type n = (size_type)CharStrlen(p);
3337 return basic_string<T, Allocator>::compare(a.begin(), a.end(), p, p + n) < 0;
3341 template <
typename T,
typename Allocator>
3342 inline bool operator>(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3348 template <
typename T,
typename Allocator>
3349 inline bool operator>(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3355 template <
typename T,
typename Allocator>
3356 inline bool operator>(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3362 template <
typename T,
typename Allocator>
3363 inline bool operator<=(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3369 template <
typename T,
typename Allocator>
3370 inline bool operator<=(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3376 template <
typename T,
typename Allocator>
3377 inline bool operator<=(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3383 template <
typename T,
typename Allocator>
3384 inline bool operator>=(
const basic_string<T, Allocator>& a,
const basic_string<T, Allocator>& b)
3390 template <
typename T,
typename Allocator>
3391 inline bool operator>=(
const typename basic_string<T, Allocator>::value_type* p,
const basic_string<T, Allocator>& b)
3397 template <
typename T,
typename Allocator>
3398 inline bool operator>=(
const basic_string<T, Allocator>& a,
const typename basic_string<T, Allocator>::value_type* p)
3404 template <
typename T,
typename Allocator>
3405 inline void swap(basic_string<T, Allocator>& a, basic_string<T, Allocator>& b)
3430 template <
typename T>
struct hash;
3435 size_t operator()(
const string& x)
const
3437 const unsigned char* p = (
const unsigned char*)x.c_str();
3438 unsigned int c, result = 2166136261U;
3439 while((c = *p++) != 0)
3440 result = (result * 16777619) ^ c;
3441 return (
size_t)result;
3450 size_t operator()(
const wstring& x)
const
3452 const wchar_t* p = (
const wchar_t*)x.c_str();
3453 unsigned int c, result = 2166136261U;
3454 while((c = *p++) != 0)
3455 result = (result * 16777619) ^ c;
3456 return (
size_t)result;
3465 #pragma warning(pop)
3468 #endif // EASTL_ABSTRACT_STRING_ENABLED
3470 #endif // Header include guard