UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CString.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "HAL/PlatformCrt.h"
9#include "Misc/Char.h"
10#include "Misc/VarArgs.h"
14
15#define MAX_SPRINTF 1024
16
18namespace ESearchCase
19{
20 enum Type
21 {
24
27 };
28};
29
31namespace ESearchDir
32{
33 enum Type
34 {
37
40 };
41}
42
45{
46 static CORE_API bool FromCStringAnsi( const ANSICHAR* String );
47 static CORE_API bool FromCStringWide( const WIDECHAR* String );
48 static CORE_API bool FromCStringUtf8( const UTF8CHAR* String );
49};
50
58template <typename T>
60{
61 typedef T CharType;
62
67 static bool IsPureAnsi(const CharType* Str)
68 {
69 if constexpr (std::is_same_v<CharType, ANSICHAR>)
70 {
71 return true;
72 }
73 else if constexpr (std::is_same_v<CharType, WIDECHAR>)
74 {
75 for (; *Str; Str++)
76 {
77 if (*Str > 0x7f)
78 {
79 return false;
80 }
81 }
82 return true;
83 }
84 else if constexpr (std::is_same_v<CharType, UTF8CHAR>)
85 {
86 for (; *Str; Str++)
87 {
88 if ((uint8)*Str > 0x7f)
89 {
90 return false;
91 }
92 }
93 return true;
94 }
95 else
96 {
97 static_assert(sizeof(CharType) == 0, "Not supported");
98 }
99 }
100
101 static bool IsPureAnsi(const CharType* Str, const SIZE_T StrLen)
102 {
103 if constexpr (std::is_same_v<CharType, ANSICHAR>)
104 {
105 return true;
106 }
107 else if constexpr (std::is_same_v<CharType, WIDECHAR>)
108 {
109 for (SIZE_T Idx = 0; Idx < StrLen; Idx++, Str++)
110 {
111 if (*Str > 0x7f)
112 {
113 return false;
114 }
115 }
116 return true;
117 }
118 else if constexpr (std::is_same_v<CharType, UTF8CHAR>)
119 {
120 for (SIZE_T Idx = 0; Idx < StrLen; Idx++, Str++)
121 {
122 if ((uint8)*Str > 0x7f)
123 {
124 return false;
125 }
126 }
127 return true;
128 }
129 else
130 {
131 static_assert(sizeof(CharType) == 0, "Not supported");
132 }
133 }
134
139 static bool IsNumeric(const CharType* Str)
140 {
141 if (*Str == '-' || *Str == '+')
142 {
143 Str++;
144 }
145
146 bool bHasDot = false;
147 while (*Str != '\0')
148 {
149 if (*Str == '.')
150 {
151 if (bHasDot)
152 {
153 return false;
154 }
155 bHasDot = true;
156 }
157 else if (!FChar::IsDigit(*Str))
158 {
159 return false;
160 }
161
162 ++Str;
163 }
164
165 return true;
166 }
167
176 static UE_FORCEINLINE_HINT CharType* Strcpy( CharType* Dest, const CharType* Src );
177
178 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
179 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
180 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
181 static inline CharType* Strcpy(CharType* Dest, SIZE_T DestCount, const CharType* Src);
182
192
201 template<SIZE_T DestCount>
202 static UE_FORCEINLINE_HINT CharType* Strcpy( CharType (&Dest)[DestCount], const CharType* Src )
203 {
204 return Strncpy( Dest, Src, DestCount);
205 }
206
215 static UE_FORCEINLINE_HINT CharType* Strcat( CharType* Dest, const CharType* Src );
216
217 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
218 UE_DEPRECATED(5.6, "Use StrncatTruncateDest instead.")
220
229 template<SIZE_T DestCount>
230 static UE_FORCEINLINE_HINT CharType* Strcat( CharType (&Dest)[DestCount], const CharType* Src )
231 {
232 return StrncatTruncateDest( Dest, DestCount, Src);
233 }
234
235 // This version was deprecated because it had a different interpretation of the length argument than CRT strncat.
236 UE_DEPRECATED(5.6, "Use StrncatTruncateDest instead.")
238 {
239 return StrncatTruncateDest(Dest, DestSize, Src);
240 }
241
253 static inline CharType* StrncatTruncateSrc(CharType* Dest, const CharType* Src, int32 SrcLen)
254 {
255 if (SrcLen <= 0 || !*Src)
256 {
257 return Dest;
258 }
259 CharType* NewDest = Dest + Strlen(Dest);
261 do
262 {
263 *NewDest++ = *Src++;
265 } while (AppendedCount < SrcLen && *Src);
266 *NewDest = CharType(0);
267 return Dest;
268 }
269
281 static inline CharType* StrncatTruncateDest(CharType* Dest, int32 DestSize, const CharType* Src)
282 {
283 if (!*Src)
284 {
285 return Dest;
286 }
287 int32 Len = Strlen(Dest);
288 if (Len + 1 >= DestSize)
289 {
290 return Dest;
291 }
292 CharType* NewDest = Dest + Len;
293 do
294 {
295 *NewDest++ = *Src++;
296 ++Len;
297 } while (*Src && Len + 1 < DestSize);
298 *NewDest = CharType(0);
299 return Dest;
300 }
301
309 static UE_FORCEINLINE_HINT CharType* Strupr( CharType* Dest, SIZE_T DestCount );
310
311
319 template<SIZE_T DestCount>
320 static UE_FORCEINLINE_HINT CharType* Strupr( CharType (&Dest)[DestCount] )
321 {
322 return Strupr( Dest, DestCount );
323 }
324
329
334
339
344
352 static const CharType* Spc( int32 NumSpaces );
353
361 static const CharType* Tab( int32 NumTabs );
362
366 static const CharType* Strfind( const CharType* Str, const CharType* Find, bool bSkipQuotedChars = false );
367
371 static const CharType* Strifind( const CharType* Str, const CharType* Find, bool bSkipQuotedChars = false );
372
377 static const CharType* StrfindDelim(const CharType* Str, const CharType* Find, const CharType* Delim=LITERAL(CharType, " \t,"));
378
385 static const CharType* Stristr(const CharType* Str, const CharType* Find);
386
393 static CharType* Stristr(CharType* Str, const CharType* Find) { return (CharType*)Stristr((const CharType*)Str, Find); }
394
403 static const CharType* Strnistr(const CharType* Str, int32 InStrLen, const CharType* Find, int32 FindLen);
404
414 {
415 return (CharType*)Strnistr((const CharType*)Str, InStrLen, Find, FindLen);
416 }
417
426 static const CharType* Strnstr(const CharType* Str, int32 InStrLen, const CharType* Find, int32 FindLen);
427
437 {
438 return (CharType*)Strnstr((const CharType*)Str, InStrLen, Find, FindLen);
439 }
440
444 static inline int32 Strlen( const CharType* String );
445
453
457 static UE_FORCEINLINE_HINT const CharType* Strstr( const CharType* String, const CharType* Find );
459
463 static UE_FORCEINLINE_HINT const CharType* Strchr( const CharType* String, CharType c );
465
469 static UE_FORCEINLINE_HINT const CharType* Strrchr( const CharType* String, CharType c );
471
475 static UE_FORCEINLINE_HINT const CharType* Strrstr( const CharType* String, const CharType* Find );
476 static inline CharType* Strrstr( CharType* String, const CharType* Find );
477
481 static inline int32 Strspn( const CharType* String, const CharType* Mask );
482
486 static inline int32 Strcspn( const CharType* String, const CharType* Mask );
487
492
497
501 static UE_FORCEINLINE_HINT float Atof( const CharType* String );
502
506 static UE_FORCEINLINE_HINT double Atod( const CharType* String );
507
515 static bool ToBool(const CharType* String)
516 {
517 if constexpr (std::is_same_v<CharType, ANSICHAR>)
518 {
520 }
521 else if constexpr (std::is_same_v<CharType, WIDECHAR>)
522 {
524 }
525 else if constexpr (std::is_same_v<CharType, UTF8CHAR>)
526 {
528 }
529 else
530 {
531 static_assert(sizeof(CharType) == 0, "Not supported");
532 return false;
533 }
534 }
535
539 static UE_FORCEINLINE_HINT int32 Strtoi( const CharType* Start, CharType** End, int32 Base );
540
544 static UE_FORCEINLINE_HINT int64 Strtoi64( const CharType* Start, CharType** End, int32 Base );
545
549 static UE_FORCEINLINE_HINT uint64 Strtoui64( const CharType* Start, CharType** End, int32 Base );
550
555
556private:
557 static int32 VARARGS SprintfImpl(CharType* Dest, const CharType* Fmt, ...);
558 static int32 VARARGS SnprintfImpl(CharType* Dest, int32 DestSize, const CharType* Fmt, ...);
559
560 template <typename SrcEncoding>
561 using TIsCharEncodingCompatibleWithCharType = TIsCharEncodingCompatibleWith<SrcEncoding, CharType>;
562
563public:
568 template <typename FmtType, typename... Types>
569 static int32 Sprintf(CharType* Dest, const FmtType& Fmt, Types... Args)
570 {
571 static_assert(TIsArrayOrRefOfTypeByPredicate<FmtType, TIsCharEncodingCompatibleWithCharType>::Value, "Formatting string must be a literal string of a char type compatible with the TCString type.");
572 static_assert((TIsValidVariadicFunctionArg<Types>::Value && ...), "Invalid argument(s) passed to TCString::Sprintf");
573
574 return SprintfImpl(Dest, (const CharType*)Fmt, Args...);
575 }
576
580 template <typename FmtType, typename... Types>
581 static int32 Snprintf(CharType* Dest, int32 DestSize, const FmtType& Fmt, Types... Args)
582 {
583 static_assert(TIsArrayOrRefOfTypeByPredicate<FmtType, TIsCharEncodingCompatibleWithCharType>::Value, "Formatting string must be a literal string of a char type compatible with the TCString type.");
584 static_assert((TIsValidVariadicFunctionArg<Types>::Value && ...), "Invalid argument(s) passed to TCString::Snprintf");
585
586 return SnprintfImpl(Dest, DestSize, (const CharType*)Fmt, Args...);
587 }
588
599};
600
605
606/*-----------------------------------------------------------------------------
607 generic TCString implementations
608-----------------------------------------------------------------------------*/
609
610template <typename CharType = TCHAR>
612{
614 static constexpr int32 MAX_SPACES = 255;
615
617 static constexpr int32 MAX_TABS = 255;
618
619 static CORE_API const CharType SpcArray[MAX_SPACES + 1];
620 static CORE_API const CharType TabArray[MAX_TABS + 1];
621};
622
623template <typename T>
629
630template <typename T>
636
637//
638// Find string in string, case sensitive, requires non-alphanumeric lead-in.
639//
640template <typename T>
642{
643 if (Find == NULL || Str == NULL)
644 {
645 return NULL;
646 }
647
648 bool Alnum = 0;
649 CharType f = *Find;
650 int32 Length = Strlen(Find++) - 1;
651 CharType c = *Str++;
653 {
654 bool bInQuotedStr = false;
655 while (c)
656 {
657 if (!bInQuotedStr && !Alnum && c == f && !Strncmp(Str, Find, Length))
658 {
659 return Str - 1;
660 }
661 Alnum = (c >= LITERAL(CharType, 'A') && c <= LITERAL(CharType, 'Z')) ||
662 (c >= LITERAL(CharType, 'a') && c <= LITERAL(CharType, 'z')) ||
663 (c >= LITERAL(CharType, '0') && c <= LITERAL(CharType, '9'));
664 if (c == LITERAL(CharType, '"'))
665 {
667 }
668 c = *Str++;
669 }
670 }
671 else
672 {
673 while (c)
674 {
675 if (!Alnum && c == f && !Strncmp(Str, Find, Length))
676 {
677 return Str - 1;
678 }
679 Alnum = (c >= LITERAL(CharType, 'A') && c <= LITERAL(CharType, 'Z')) ||
680 (c >= LITERAL(CharType, 'a') && c <= LITERAL(CharType, 'z')) ||
681 (c >= LITERAL(CharType, '0') && c <= LITERAL(CharType, '9'));
682 c = *Str++;
683 }
684 }
685 return NULL;
686}
687
688//
689// Find string in string, case insensitive, requires non-alphanumeric lead-in.
690//
691template <typename T>
693{
694 if( Find == NULL || Str == NULL )
695 {
696 return NULL;
697 }
698
699 bool Alnum = 0;
700 CharType f = ( *Find < LITERAL(CharType, 'a') || *Find > LITERAL(CharType, 'z') ) ? (*Find) : (CharType)(*Find + LITERAL(CharType,'A') - LITERAL(CharType,'a'));
701 int32 Length = Strlen(Find++)-1;
702 CharType c = *Str++;
703
705 {
706 bool bInQuotedStr = false;
707 while( c )
708 {
709 if( c >= LITERAL(CharType, 'a') && c <= LITERAL(CharType, 'z') )
710 {
711 c += LITERAL(CharType, 'A') - LITERAL(CharType, 'a');
712 }
713 if( !bInQuotedStr && !Alnum && c==f && !Strnicmp(Str,Find,Length) )
714 {
715 return Str-1;
716 }
717 Alnum = (c>=LITERAL(CharType,'A') && c<=LITERAL(CharType,'Z')) ||
718 (c>=LITERAL(CharType,'0') && c<=LITERAL(CharType,'9'));
719 if (c == LITERAL(CharType, '"'))
720 {
722 }
723 c = *Str++;
724 }
725 }
726 else
727 {
728 while( c )
729 {
730 if( c >= LITERAL(CharType, 'a') && c <= LITERAL(CharType, 'z') )
731 {
732 c += LITERAL(CharType, 'A') - LITERAL(CharType, 'a');
733 }
734 if( !Alnum && c==f && !Strnicmp(Str,Find,Length) )
735 {
736 return Str-1;
737 }
738 Alnum = (c>=LITERAL(CharType,'A') && c<=LITERAL(CharType,'Z')) ||
739 (c>=LITERAL(CharType,'0') && c<=LITERAL(CharType,'9'));
740 c = *Str++;
741 }
742 }
743 return NULL;
744}
745
746//
747// Finds string in string, case insensitive, requires the string be surrounded by one the specified
748// delimiters, or the start or end of the string.
749//
750template <typename T>
752{
753 if( Find == NULL || Str == NULL )
754 {
755 return NULL;
756 }
757
758 int32 Length = Strlen(Find);
759 const T* Found = Stristr(Str, Find);
760 if( Found )
761 {
762 // check if this occurrence is delimited correctly
763 if( (Found==Str || Strchr(Delim, Found[-1])!=NULL) && // either first char, or following a delim
764 (Found[Length]==LITERAL(CharType,'\0') || Strchr(Delim, Found[Length])!=NULL) ) // either last or with a delim following
765 {
766 return Found;
767 }
768
769 // start searching again after the first matched character
770 for(;;)
771 {
772 Str = Found+1;
773 Found = Stristr(Str, Find);
774
775 if( Found == NULL )
776 {
777 return NULL;
778 }
779
780 // check if the next occurrence is delimited correctly
781 if( (Strchr(Delim, Found[-1])!=NULL) && // match is following a delim
782 (Found[Length]==LITERAL(CharType,'\0') || Strchr(Delim, Found[Length])!=NULL) ) // either last or with a delim following
783 {
784 return Found;
785 }
786 }
787 }
788
789 return NULL;
790}
791
798template <typename T>
800{
801 // Note this implementation is not reducible to Strnistr because we need to avoid calling strlen(Str) to
802 // avoid scanning it twice
803
804 // both strings must be valid
805 if( Find == nullptr || Str == nullptr )
806 {
807 return nullptr;
808 }
809
810 // get upper-case first letter of the find string (to reduce the number of full strnicmps)
812 if (!FindInitial)
813 {
814 // When searching for the empty string, always return index of the first element of Str even if Str is empty.
815 return Str;
816 }
817 // get length of find string, and increment past first letter
818 int32 Length = Strlen(Find++) - 1;
819 // get the first letter of the search string, and increment past it
820 CharType StrChar = *Str++;
821 // while we aren't at end of string...
822 while (StrChar)
823 {
824 // make sure it's upper-case
826 // if it matches the first letter of the find string, do a case-insensitive string compare for the length of the find string
827 if (StrChar == FindInitial && !Strnicmp(Str, Find, Length))
828 {
829 // if we found the string, then return a pointer to the beginning of it in the search string
830 return Str-1;
831 }
832 // go to next letter
833 StrChar = *Str++;
834 }
835
836 // if nothing was found, return nullptr
837 return nullptr;
838}
839
840template <typename T>
842{
843 if (FindLen <= 0)
844 {
845 checkf(FindLen >= 0, TEXT("Invalid FindLen: %d"), FindLen);
846 return Str;
847 }
848 if (InStrLen < FindLen)
849 {
850 checkf(InStrLen >= 0, TEXT("Invalid InStrLen: %d"), InStrLen);
851 return nullptr;
852 }
853
854 // get upper-case first letter of the find string (to reduce the number of full strnicmps)
856 // Set FindSuffix,FindSuffixLength to the characters of Find after the first letter
858 const CharType* FindSuffix = Find + 1;
859
860 // while the length of the remaining string is >= FindLen
861 const CharType* StrLastChance = Str + InStrLen - FindLen;
862 while (Str <= StrLastChance)
863 {
864 CharType StrChar = *Str++;
865
866 // make sure it's upper-case
868 // if it matches the first letter of the find string, do a case-insensitive string compare for the length of the find string
869 if (StrChar == FindInitial && !Strnicmp(Str, FindSuffix, FindSuffixLength))
870 {
871 // if we found the string, then return a pointer to the beginning of it in the search string
872 return Str - 1;
873 }
874 }
875
876 // if nothing was found, return nullptr
877 return nullptr;
878}
879
880template <typename T>
882{
883 if (FindLen <= 0)
884 {
885 checkf(FindLen >= 0, TEXT("Invalid FindLen: %d"), FindLen);
886 return Str;
887 }
888 if (InStrLen < FindLen)
889 {
890 checkf(InStrLen >= 0, TEXT("Invalid InStrLen: %d"), InStrLen);
891 return nullptr;
892 }
893
894 // get first letter of the find string (to reduce the number of full strncmps)
895 const CharType FindInitial = *Find;
896 // Set FindSuffix,FindSuffixLength to the characters of Find after the first letter
897 const int32 FindSuffixLength = FindLen - 1;
898 const CharType* FindSuffix = Find + 1;
899
900 // while the length of the remaining string is >= FindLen
901 const CharType* StrLastChance = Str + InStrLen - FindLen;
902
903 if constexpr (sizeof(CharType) >= 1 && sizeof(CharType) <= 2)
904 {
905 constexpr uint64 SignBit = sizeof(CharType) == 1 ? 0x80ull : 0x8000ull;
906 constexpr uint64 Mask = sizeof(CharType) == 1 ? 0xFFull : 0xFFFFull;
907 constexpr uint64 Ones64 = sizeof(CharType) == 1 ? 0x0101010101010101ull : 0x0001000100010001ull;
908 constexpr uint64 Positive64 = sizeof(CharType) == 1 ? 0x7F7F7F7F7F7F7F7Full : 0x7FFF7FFF7FFF7FFFull;
909 constexpr uint64 SignBit64 = sizeof(CharType) == 1 ? 0x8080808080808080ull : 0x8000800080008000ull;
910 constexpr uint64 CharPer64 = sizeof(uint64) / sizeof(CharType);
911 constexpr uint64 BitPerChar = sizeof(CharType) == 1 ? 8 : 16;
912
914 if (InStrLen >= CharPer64)
915 {
916 // Process normally if we're unaligned
917 for (; (UPTRINT(Str) & (BitPerChar-1)) && InStrLen > 1; --InStrLen)
918 {
919 CharType StrChar = *Str++;
920
921 // if it matches the first letter of the find string, do a string compare for the length of the find string
923 {
924 // if we found the string, then return a pointer to the beginning of it in the search string
925 return Str - 1;
926 }
927 }
928
929 // Broadcast the initial value in each slots.
931
932 for (; InStrLen >= (int32)CharPer64; Str += CharPer64, InStrLen -= (int32)CharPer64)
933 {
934 uint64 StrValue = *(const uint64*)Str;
935 // We want to test each slots perfect match with the initial character
936 // The trick is to avoid overflowing a slot into another one.
937 // So we XOR and NEGATE so we end up with 0xFF when the character match.
938 // Then we remove the sign bit with 0x7F and ADD one, which will end up with 0x80
939 // if all the bits are set. We also AND with 0x80 to test the sign bit separately.
940 // And then we AND those two things together that will end up with 0x80 for each
941 // slot where there is a match.
944
945 // If any slot has a match, begin analysis
946 if (StrValue)
947 {
948 for (const CharType* InnerStr = Str; StrValue; StrValue >>= BitPerChar, ++InnerStr)
949 {
951 {
952 return InnerStr;
953 }
954 }
955 }
956 }
957 }
958 }
959
960 while (Str <= StrLastChance)
961 {
962 CharType StrChar = *Str++;
963
964 // if it matches the first letter of the find string, do a string compare for the length of the find string
965 if (StrChar == FindInitial && !Strncmp(Str, FindSuffix, FindSuffixLength))
966 {
967 // if we found the string, then return a pointer to the beginning of it in the search string
968 return Str - 1;
969 }
970 }
971
972 // if nothing was found, return nullptr
973 return nullptr;
974}
975
976template <typename T> UE_FORCEINLINE_HINT
978{
979 return FPlatformString::Strcpy(Dest, Src);
980}
981
982template <typename T> inline
983typename TCString<T>::CharType* TCString<T>::Strcpy(CharType* Dest, SIZE_T DestCount, const CharType* Src)
984{
986 return FPlatformString::Strcpy(Dest, DestCount, Src);
988}
989
990template <typename T> inline
992{
993 FPlatformString::Strncpy(Dest, Src, MaxLen);
994 return Dest;
995}
996
997template <typename T> UE_FORCEINLINE_HINT
999{
1000 return FPlatformString::Strcat(Dest, Src);
1001}
1002
1003template <typename T> inline
1005{
1007 return FPlatformString::Strcat(Dest, DestCount, Src);
1009}
1010
1011template <typename T> UE_FORCEINLINE_HINT
1013{
1014 return FPlatformString::Strupr(Dest, DestCount);
1015}
1016
1017template <typename T> UE_FORCEINLINE_HINT
1019{
1020 return FPlatformString::Strcmp(String1, String2);
1021}
1022
1023template <typename T> UE_FORCEINLINE_HINT
1025{
1026 return FPlatformString::Strncmp(String1, String2, Count);
1027}
1028
1029template <typename T> UE_FORCEINLINE_HINT
1031{
1032 return FPlatformString::Stricmp(String1, String2);
1033}
1034
1035template <typename T> UE_FORCEINLINE_HINT
1037{
1038 return FPlatformString::Strnicmp(String1, String2, Count);
1039}
1040
1041namespace UE::Core::Private
1042{
1043 CORE_API int32 Strlen32(const UTF32CHAR* String);
1044}
1045
1046template <typename T>
1048{
1049 if constexpr (std::is_same_v<T, UTF32CHAR>)
1050 {
1052 }
1053 else
1054 {
1055 return FPlatformString::Strlen(String);
1056 }
1057}
1058
1059template <typename T> UE_FORCEINLINE_HINT
1061{
1062 return FPlatformString::Strnlen(String, StringSize);
1063}
1064
1065template <typename T> UE_FORCEINLINE_HINT
1067{
1068 return FPlatformString::Strstr(String, Find);
1069}
1070
1071template <typename T> UE_FORCEINLINE_HINT
1073{
1074 return (CharType*)FPlatformString::Strstr(String, Find);
1075}
1076
1077template <typename T> UE_FORCEINLINE_HINT
1079{
1080 return FPlatformString::Strchr(String, c);
1081}
1082
1083template <typename T> UE_FORCEINLINE_HINT
1085{
1086 return (CharType*)FPlatformString::Strchr(String, c);
1087}
1088
1089template <typename T> UE_FORCEINLINE_HINT
1091{
1092 return FPlatformString::Strrchr(String, c);
1093}
1094
1095template <typename T> UE_FORCEINLINE_HINT
1097{
1098 return (CharType*)FPlatformString::Strrchr(String, c);
1099}
1100
1101template <typename T> UE_FORCEINLINE_HINT
1103{
1104 return Strrstr((CharType*)String, Find);
1105}
1106
1107template <typename T> inline
1109{
1110 if (*Find == (CharType)0)
1111 {
1112 return String + Strlen(String);
1113 }
1114
1115 CharType* Result = nullptr;
1116 for (;;)
1117 {
1118 CharType* Found = Strstr(String, Find);
1119 if (!Found)
1120 {
1121 return Result;
1122 }
1123
1124 Result = Found;
1125 String = Found + 1;
1126 }
1127}
1128
1129template <typename T> inline
1131{
1132 const CharType* StringIt = String;
1133 while (*StringIt)
1134 {
1135 for (const CharType* MaskIt = Mask; *MaskIt; ++MaskIt)
1136 {
1137 if (*StringIt == *MaskIt)
1138 {
1139 goto NextChar;
1140 }
1141 }
1142
1144
1145 NextChar:
1146 ++StringIt;
1147 }
1148
1150}
1151
1152template <typename T> inline
1154{
1155 const CharType* StringIt = String;
1156 while (*StringIt)
1157 {
1158 for (const CharType* MaskIt = Mask; *MaskIt; ++MaskIt)
1159 {
1160 if (*StringIt == *MaskIt)
1161 {
1163 }
1164 }
1165
1166 ++StringIt;
1167 }
1168
1170}
1171
1172template <typename T> UE_FORCEINLINE_HINT
1174{
1175 return FPlatformString::Atoi(String);
1176}
1177
1178template <typename T> UE_FORCEINLINE_HINT
1180{
1181 return FPlatformString::Atoi64(String);
1182}
1183
1184template <typename T> UE_FORCEINLINE_HINT
1186{
1187 return FPlatformString::Atof(String);
1188}
1189
1190template <typename T> UE_FORCEINLINE_HINT
1192{
1193 return FPlatformString::Atod(String);
1194}
1195
1196template <typename T> UE_FORCEINLINE_HINT
1198{
1199 return FPlatformString::Strtoi(Start, End, Base);
1200}
1201
1202template <typename T> UE_FORCEINLINE_HINT
1204{
1205 return FPlatformString::Strtoi64(Start, End, Base);
1206}
1207
1208template <typename T> UE_FORCEINLINE_HINT
1210{
1211 return FPlatformString::Strtoui64(Start, End, Base);
1212}
1213
1214
1215template <typename T> UE_FORCEINLINE_HINT
1217{
1218 return FPlatformString::Strtok(TokenString, Delim, Context);
1219}
1220
1221template <typename T> UE_FORCEINLINE_HINT
1223{
1224 return FPlatformString::GetVarArgs(Dest, DestSize, Fmt, ArgPtr);
1225}
1226
1227template <typename T>
1228int32 TCString<T>::SprintfImpl(CharType* Dest, const CharType* Fmt, ...)
1229{
1230 static_assert(std::is_same_v<CharType, ANSICHAR> || std::is_same_v<CharType, WIDECHAR> || std::is_same_v<CharType, UTF8CHAR>, "Not supported");
1231
1232 int32 Result = -1;
1233 GET_TYPED_VARARGS_RESULT(CharType, Dest, MAX_SPRINTF, MAX_SPRINTF - 1, Fmt, Fmt, Result);
1234 return Result;
1235}
1236
1237template <typename T>
1238int32 TCString<T>::SnprintfImpl(CharType* Dest, int32 DestSize, const CharType* Fmt, ...)
1239{
1240 static_assert(std::is_same_v<CharType, ANSICHAR> || std::is_same_v<CharType, WIDECHAR> || std::is_same_v<CharType, UTF8CHAR>, "Not supported");
1241
1242 int32 Result = -1;
1243 GET_TYPED_VARARGS_RESULT(CharType, Dest, DestSize, DestSize - 1, Fmt, Fmt, Result);
1244 return Result;
1245}
#define NULL
Definition oodle2base.h:134
#define VARARGS
Definition AndroidPlatform.h:134
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define MAX_SPRINTF
Definition CString.h:15
TCString< ANSICHAR > FCStringAnsi
Definition CString.h:602
TCString< WIDECHAR > FCStringWide
Definition CString.h:603
TCString< TCHAR > FCString
Definition CString.h:601
TCString< UTF8CHAR > FCStringUtf8
Definition CString.h:604
ENGINE_API void StringSize(const UFont *Font, int32 &XL, int32 &YL, FStringView Text)
Definition Canvas.cpp:1181
#define LITERAL(CharType, StringLiteral)
Definition Char.h:31
#define UE_PTRDIFF_TO_INT32(argument)
Definition CoreMiscDefines.h:442
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::UTF32CHAR UTF32CHAR
A 32-bit character containing a UTF32 (Unicode, 32-bit, fixed-width) code unit.
Definition Platform.h:1143
#define UE_NODEBUG
Definition Platform.h:817
FPlatformTypes::WIDECHAR WIDECHAR
A wide character. Normally a signed type.
Definition Platform.h:1133
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
FPlatformTypes::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
#define GET_TYPED_VARARGS_RESULT(CharType, msg, msgsize, len, lastarg, fmt, result)
Definition VarArgs.h:29
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition CString.h:19
Type
Definition CString.h:21
@ IgnoreCase
Definition CString.h:26
@ CaseSensitive
Definition CString.h:23
Definition CString.h:32
Type
Definition CString.h:34
@ FromEnd
Definition CString.h:39
@ FromStart
Definition CString.h:36
implementation
Definition PlayInEditorLoadingScope.h:8
CORE_API int32 Strlen32(const UTF32CHAR *String)
Definition CString.cpp:187
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
Definition CString.h:45
static CORE_API bool FromCStringWide(const WIDECHAR *String)
Definition CString.cpp:123
static CORE_API bool FromCStringAnsi(const ANSICHAR *String)
Definition CString.cpp:114
static CORE_API bool FromCStringUtf8(const UTF8CHAR *String)
Definition CString.cpp:155
Definition CString.h:612
static CORE_API const CharType SpcArray[MAX_SPACES+1]
Definition CString.h:619
static constexpr int32 MAX_TABS
Definition CString.h:617
static CORE_API const CharType TabArray[MAX_TABS+1]
Definition CString.h:620
static constexpr int32 MAX_SPACES
Definition CString.h:614
Definition CString.h:60
static UE_FORCEINLINE_HINT CharType * Strtok(CharType *TokenString, const CharType *Delim, CharType **Context)
Definition CString.h:1216
static UE_FORCEINLINE_HINT int32 Strnlen(const CharType *String, SIZE_T StringSize)
Definition CString.h:1060
static UE_FORCEINLINE_HINT int32 Atoi(const CharType *String)
Definition CString.h:1173
static int32 Snprintf(CharType *Dest, int32 DestSize, const FmtType &Fmt, Types... Args)
Definition CString.h:581
static int32 Strspn(const CharType *String, const CharType *Mask)
Definition CString.h:1130
static CharType * Strnistr(CharType *Str, int32 InStrLen, const CharType *Find, int32 FindLen)
Definition CString.h:413
static UE_FORCEINLINE_HINT int32 Strcmp(const CharType *String1, const CharType *String2)
Definition CString.h:1018
static CharType * Stristr(CharType *Str, const CharType *Find)
Definition CString.h:393
static bool IsPureAnsi(const CharType *Str, const SIZE_T StrLen)
Definition CString.h:101
static UE_FORCEINLINE_HINT int32 Stricmp(const CharType *String1, const CharType *String2)
Definition CString.h:1030
static UE_FORCEINLINE_HINT int32 Strtoi(const CharType *Start, CharType **End, int32 Base)
Definition CString.h:1197
static UE_FORCEINLINE_HINT float Atof(const CharType *String)
Definition CString.h:1185
static int32 Strlen(const CharType *String)
Definition CString.h:1047
static const CharType * Tab(int32 NumTabs)
Definition CString.h:631
static UE_FORCEINLINE_HINT int32 Strncmp(const CharType *String1, const CharType *String2, SIZE_T Count)
Definition CString.h:1024
static CharType * StrncatTruncateDest(CharType *Dest, int32 DestSize, const CharType *Src)
Definition CString.h:281
static UE_FORCEINLINE_HINT double Atod(const CharType *String)
Definition CString.h:1191
static CharType * Strncpy(CharType *Dest, const CharType *Src, SIZE_T MaxLen)
Definition CString.h:991
static UE_FORCEINLINE_HINT CharType * Strcpy(CharType *Dest, const CharType *Src)
Definition CString.h:977
static UE_FORCEINLINE_HINT const CharType * Strrstr(const CharType *String, const CharType *Find)
Definition CString.h:1102
static const CharType * Strnistr(const CharType *Str, int32 InStrLen, const CharType *Find, int32 FindLen)
Definition CString.h:841
static UE_FORCEINLINE_HINT const CharType * Strchr(const CharType *String, CharType c)
Definition CString.h:1078
static UE_FORCEINLINE_HINT int32 GetVarArgs(CharType *Dest, SIZE_T DestSize, const CharType *&Fmt, va_list ArgPtr)
Definition CString.h:1222
static UE_FORCEINLINE_HINT CharType * Strupr(CharType(&Dest)[DestCount])
Definition CString.h:320
static UE_FORCEINLINE_HINT int64 Atoi64(const CharType *String)
Definition CString.h:1179
static UE_FORCEINLINE_HINT int32 Strnicmp(const CharType *String1, const CharType *String2, SIZE_T Count)
Definition CString.h:1036
static const CharType * Strfind(const CharType *Str, const CharType *Find, bool bSkipQuotedChars=false)
Definition CString.h:641
static UE_FORCEINLINE_HINT CharType * Strcat(CharType *Dest, const CharType *Src)
Definition CString.h:998
static bool IsPureAnsi(const CharType *Str)
Definition CString.h:67
static const CharType * Strifind(const CharType *Str, const CharType *Find, bool bSkipQuotedChars=false)
Definition CString.h:692
static CharType * Strncat(CharType *Dest, const CharType *Src, int32 DestSize)
Definition CString.h:237
static bool ToBool(const CharType *String)
Definition CString.h:515
static int32 Strcspn(const CharType *String, const CharType *Mask)
Definition CString.h:1153
static bool IsNumeric(const CharType *Str)
Definition CString.h:139
static UE_FORCEINLINE_HINT uint64 Strtoui64(const CharType *Start, CharType **End, int32 Base)
Definition CString.h:1209
T CharType
Definition CString.h:61
static UE_FORCEINLINE_HINT CharType * Strupr(CharType *Dest, SIZE_T DestCount)
Definition CString.h:1012
static const CharType * Spc(int32 NumSpaces)
Definition CString.h:624
static CharType * StrncatTruncateSrc(CharType *Dest, const CharType *Src, int32 SrcLen)
Definition CString.h:253
static const CharType * Stristr(const CharType *Str, const CharType *Find)
Definition CString.h:799
static const CharType * Strnstr(const CharType *Str, int32 InStrLen, const CharType *Find, int32 FindLen)
Definition CString.h:881
static CharType * Strnstr(CharType *Str, int32 InStrLen, const CharType *Find, int32 FindLen)
Definition CString.h:436
static UE_FORCEINLINE_HINT const CharType * Strrchr(const CharType *String, CharType c)
Definition CString.h:1090
static const CharType * StrfindDelim(const CharType *Str, const CharType *Find, const CharType *Delim=LITERAL(CharType, " \t,"))
Definition CString.h:751
static UE_FORCEINLINE_HINT int64 Strtoi64(const CharType *Start, CharType **End, int32 Base)
Definition CString.h:1203
static int32 Sprintf(CharType *Dest, const FmtType &Fmt, Types... Args)
Definition CString.h:569
static UE_FORCEINLINE_HINT const CharType * Strstr(const CharType *String, const CharType *Find)
Definition CString.h:1066
static bool IsDigit(CharType Char)
Definition Char.h:240
static CharType ToUpper(CharType Char)
Definition Char.h:80
Definition IsArrayOrRefOfTypeByPredicate.h:13
Definition IsCharEncodingCompatibleWith.h:65
Definition IsValidVariadicFunctionArg.h:14