UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
NameTypes.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"
7#include "HAL/UnrealMemory.h"
11#include "HAL/CriticalSection.h"
14#include "UObject/UnrealNames.h"
15#include "Templates/Atomic.h"
18#include "Misc/StringBuilder.h"
19#include "Misc/UEOps.h"
20#include "Trace/Trace.h"
21
22/*----------------------------------------------------------------------------
23 Definitions.
24----------------------------------------------------------------------------*/
25
32#ifndef WITH_CASE_PRESERVING_NAME
33 #define WITH_CASE_PRESERVING_NAME WITH_EDITORONLY_DATA
34#endif
35
36// Should the number part of the fname be stored in the name table or in the FName instance?
37// Storing it in the name table may save memory overall but new number suffixes will cause the name table to grow like unique strings do.
38#ifndef UE_FNAME_OUTLINE_NUMBER
39 #define UE_FNAME_OUTLINE_NUMBER 0
40#endif // UE_FNAME_OUTLINE_NUMBER
41
42// Allows overriding the alignment of FNameEntry. This decreases the granularity of memory allocation for FNames and
43// therefore allows more data to be stored as FNames with the potential of increased waste.
44// See the details of FNameEntryId encoding.
45// Setting this to a nonzero value less than the natural alignment of FNameEntry will cause a compiler error.
46#ifndef UE_FNAME_ENTRY_ALIGNMENT
47 #if WITH_EDITOR
48 #define UE_FNAME_ENTRY_ALIGNMENT 8
49 #else
50 #define UE_FNAME_ENTRY_ALIGNMENT 0
51 #endif
52#endif // UE_FNAME_ENTRY_ALIGNMENT
53
54class FText;
55
57enum {NAME_SIZE = 1024};
58
59struct FMinimalName;
60struct FScriptName;
61struct FNumberedEntry;
62class FName;
63
64// Generic constructor/initializer struct to make Clang keep type debug info needed for debug visualizers
66
69{
70 constexpr static bool bHasIntrusiveUnsetOptionalState = true;
72
73 // Default initialize to be equal to NAME_None
74 constexpr FNameEntryId() : Value(0) {}
75 constexpr FNameEntryId(ENoInit) {}
76 constexpr explicit FNameEntryId(FIntrusiveUnsetOptionalState) : Value(~0u) {}
77
78 constexpr bool IsNone() const
79 {
80 return Value == 0;
81 }
82
85 bool LexicalLess(FNameEntryId Rhs) const { return CompareLexical(Rhs) < 0; }
86
89 bool LexicalSensitiveLess(FNameEntryId Rhs) const { return CompareLexicalSensitive(Rhs) < 0; }
90
92 int32 CompareFast(FNameEntryId Rhs) const { return Value - Rhs.Value; };
93 bool FastLess(FNameEntryId Rhs) const { return CompareFast(Rhs) < 0; }
94
96 bool UEOpLessThan(FNameEntryId Rhs) const { return Value < Rhs.Value; }
97
99 bool UEOpEquals(FNameEntryId Rhs) const { return Value == Rhs.Value; }
100
103 {
104 return Value == ~0u;
105 }
106
107 // Returns true if this FNameEntryId is not equivalent to NAME_None
108 constexpr explicit operator bool() const { return Value != 0; }
109
111 constexpr uint32 ToUnstableInt() const { return Value; }
112
115 {
117 Id.Value = UnstableInt;
118 return Id;
119 }
120
122 {
123 return Ename == NAME_None ? FNameEntryId() : FromValidEName(Ename);
124 }
125
126 inline bool UEOpEquals(EName Ename) const
127 {
128 return Ename == NAME_None ? Value == 0 : Value == FromValidENamePostInit(Ename).Value;
129 }
130
131private:
132 uint32 Value;
133
134 CORE_API static FNameEntryId FromValidEName(EName Ename);
135 CORE_API static FNameEntryId FromValidENamePostInit(EName Ename);
136
137public:
139
142};
143
151
152#define checkName checkSlow
153
157#define NAME_NO_NUMBER_INTERNAL 0
158
160#define NAME_INTERNAL_TO_EXTERNAL(x) (x - 1)
161#define NAME_EXTERNAL_TO_INTERNAL(x) (x + 1)
162
164#define NAME_NO_NUMBER NAME_INTERNAL_TO_EXTERNAL(NAME_NO_NUMBER_INTERNAL)
165
166
168#define SUBOBJECT_DELIMITER_ANSI ":"
169#define SUBOBJECT_DELIMITER TEXT(SUBOBJECT_DELIMITER_ANSI)
170
172#define SUBOBJECT_DELIMITER_CHAR_ANSI ':'
173#define SUBOBJECT_DELIMITER_CHAR TEXT(SUBOBJECT_DELIMITER_CHAR_ANSI)
174
176#define INVALID_NAME_CHARACTERS TEXT("\"' ,\n\r\t")
177
179#define INVALID_OBJECTNAME_CHARACTERS TEXT("\"' ,/.:|&!~\n\r\t@#(){}[]=;^%$`")
180
182#define INVALID_OBJECTPATH_CHARACTERS TEXT("\"' ,|&!~\n\r\t@#(){}[]=;^%$`")
183
185#define INVALID_LONGPACKAGE_CHARACTERS TEXT("\\:*?\"<>|' ,.&!~\n\r\t@#")
186
188#define VALID_SAVEDDIRSUFFIX_CHARACTERS TEXT("_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
189
191#define NAMED_PAK_CHUNK_DELIMITER_CHAR TEXT('-')
192
193enum class ENameCase : uint8
194{
197};
198
200
214
215namespace UE::Core::Private
216{
217
228template <typename CharType>
229static constexpr uint32 ParseNumberFromName(const CharType* Name, int32& InOutLen)
230{
231 int32 Digits = 0;
232 for (const CharType* It = Name + InOutLen - 1; It >= Name && *It >= '0' && *It <= '9'; --It)
233 {
234 ++Digits;
235 }
236
237 const CharType* FirstDigit = Name + InOutLen - Digits;
238 constexpr int32 MaxDigitsInt32 = 10;
239 if (Digits && Digits < InOutLen && FirstDigit[-1] == '_' && Digits <= MaxDigitsInt32 && (Digits == 1 || *FirstDigit != '0'))
240 {
241 int64 Number = 0;
242 for (int32 Index = 0; Index < Digits; ++Index)
243 {
244 Number = 10 * Number + (FirstDigit[Index] - '0');
245 }
246 if (Number < MAX_int32)
247 {
248 InOutLen -= 1 + Digits;
249 return static_cast<uint32>(NAME_EXTERNAL_TO_INTERNAL(Number));
250 }
251 }
252
254}
255
256} // UE::Core::Private
257
258/*----------------------------------------------------------------------------
259 FNameEntry.
260----------------------------------------------------------------------------*/
261
264{
266#if WITH_CASE_PRESERVING_NAME
267 uint16 Len : 15;
268#else
269 static constexpr inline uint32 ProbeHashBits = 5;
272#endif
273};
274
279{
280private:
281#if WITH_CASE_PRESERVING_NAME
282 FNameEntryId ComparisonId;
283#endif
285
286 // Unaligned to reduce alignment waste for non-numbered entries
287 struct FNumberedData
288 {
289#if UE_FNAME_OUTLINE_NUMBER
290#if WITH_CASE_PRESERVING_NAME // ComparisonId is 4B-aligned, 4B-align Id/Number by 2B pad after 2B Header
291 uint8 Pad[sizeof(Header) % alignof(decltype(ComparisonId))];
292#endif
293 uint8 Id[sizeof(FNameEntryId)];
294 uint8 Number[sizeof(uint32)];
295#endif // UE_FNAME_OUTLINE_NUMBER
296 };
297
298 union
299 {
302 uint8 NameData[0];
303 FNumberedData NumberedName;
304 };
305
306
308 FNameEntry(const FNameEntry&) = delete;
309 FNameEntry(FNameEntry&&) = delete;
310 FNameEntry& operator=(const FNameEntry&) = delete;
311 FNameEntry& operator=(FNameEntry&&) = delete;
312
313public:
315 FORCEINLINE bool IsWide() const { return Header.bIsWide; }
316 FORCEINLINE int32 GetNameLength() const { return Header.Len; }
317 CORE_API int32 GetNameLengthUtf8() const;
318#if UE_FNAME_OUTLINE_NUMBER
319 FORCEINLINE bool IsNumbered() const { return Header.Len == 0; }
320#else
321 FORCEINLINE bool IsNumbered() const { return false; }
322#endif
323
325 CORE_API void GetUnterminatedName(TCHAR* OutName, uint32 OutSize) const;
326
328 CORE_API void GetName(TCHAR(&OutName)[NAME_SIZE]) const;
329
331 CORE_API void GetAnsiName(ANSICHAR(&OutName)[NAME_SIZE]) const;
332
334 CORE_API void GetWideName(WIDECHAR(&OutName)[NAME_SIZE]) const;
335
337 CORE_API FString GetPlainNameString() const;
338
340 CORE_API FUtf8String GetPlainNameUtf8String() const;
341
344 CORE_API void AppendNameToString(FUtf8String& OutString) const;
345
347 CORE_API void AppendNameToString(FWideStringBuilderBase& OutString) const;
348 CORE_API void AppendNameToString(FUtf8StringBuilderBase& OutString) const;
349
351 CORE_API void AppendAnsiNameToString(FAnsiStringBuilderBase& OutString) const;
352
354 CORE_API void AppendNameToPathString(FString& OutString) const;
355
356 CORE_API void DebugDump(FOutputDevice& Out) const;
357
358 CORE_API int32 GetSizeInBytes() const;
359
360 CORE_API void Write(FArchive& Ar) const;
361
362 static constexpr int32 GetDataOffset() { return offsetof(FNameEntry, NameData); }
364private:
365 friend class FName;
366 friend struct FNameHelper;
368 friend class FNamePoolShardBase;
369 friend class FNamePool;
370 void CopyUnterminatedName(ANSICHAR* OutName, uint32 Len) const;
371 void CopyUnterminatedName(WIDECHAR* OutName, uint32 Len) const;
372 void CopyAndConvertUnterminatedName(TCHAR* OutName, uint32 Len) const;
373 const ANSICHAR* GetUnterminatedName(ANSICHAR(&OptionalDecodeBuffer)[NAME_SIZE]) const;
374 const WIDECHAR* GetUnterminatedName(WIDECHAR(&OptionalDecodeBuffer)[NAME_SIZE]) const;
375
376#if UE_FNAME_OUTLINE_NUMBER
377 // @pre IsNumbered()
378 FORCEINLINE const FNumberedEntry& GetNumberedName() const { return reinterpret_cast<const FNumberedEntry&>(NumberedName.Id[0]); }
379 uint32 GetNumber() const;
380#endif // UE_FNAME_OUTLINE_NUMBER
381};
382
387{
388 bool bIsWide = false;
389
390 union
391 {
394 };
395
396 // These are not used anymore but recalculated on save to maintain serialization format
397 uint16 NonCasePreservingHash = 0;
398 uint16 CasePreservingHash = 0;
399
402
406 ANSICHAR const* GetAnsiName() const
407 {
408 check(!bIsWide);
409 return AnsiName;
410 }
411
415 WIDECHAR const* GetWideName() const
416 {
417 check(bIsWide);
418 return WideName;
419 }
420
424 CORE_API FString GetPlainNameString() const;
425
428 {
429 return Ar << *E;
430 }
431};
432
439{
440 friend FName;
441
443
445 : Index(FNameEntryId::FromEName(N))
446 {
447 }
448
449 FORCEINLINE explicit FMinimalName(const FName& Name);
450 FORCEINLINE bool IsNone() const;
451 FORCEINLINE bool UEOpLessThan(FMinimalName Rhs) const;
452
453private:
456#if !UE_FNAME_OUTLINE_NUMBER
459#endif // UE_FNAME_OUTLINE_NUMBE
460
461public:
462#if UE_FNAME_OUTLINE_NUMBER
463 FORCEINLINE bool UEOpEquals(FMinimalName Rhs) const
464 {
465 return Index == Rhs.Index;
466 }
468 {
469 return GetTypeHash(Name.Index);
470 }
471#else
473 {
474 return Index == Rhs.Index && Number == Rhs.Number;
475 }
477 {
478 return GetTypeHash(Name.Index) + Name.Number;
479 }
480#endif
481};
482
491{
492 friend FName;
493
495
497 : ComparisonIndex(FNameEntryId::FromEName(Ename))
498 , DisplayIndex(ComparisonIndex)
499 {
500 }
501
502 FORCEINLINE explicit FScriptName(const FName& Name);
503 FORCEINLINE bool IsNone() const;
504 inline bool UEOpEquals(EName Name) const { return UEOpEquals(FScriptName(Name)); }
505
506 CORE_API FString ToString() const;
508
509 // The internal structure of FScriptName is private in order to handle UE_FNAME_OUTLINE_NUMBER
510private:
512 FNameEntryId ComparisonIndex;
514 FNameEntryId DisplayIndex;
515#if UE_FNAME_OUTLINE_NUMBER
516 uint32 Dummy = 0; // Dummy to keep the size the same regardless of build configuration, but change the name so trying to use Number is a compile error
517#else // UE_FNAME_OUTLINE_NUMBER
519 uint32 Number = NAME_NO_NUMBER_INTERNAL;
520#endif // UE_FNAME_OUTLINE_NUMBER
521
522public:
523#if UE_FNAME_OUTLINE_NUMBER
524 FORCEINLINE bool UEOpEquals(FScriptName Rhs) const
525 {
526 return ComparisonIndex == Rhs.ComparisonIndex;
527 }
528 friend FORCEINLINE uint32 GetTypeHash(FScriptName Name)
529 {
530 return GetTypeHash(Name.ComparisonIndex);
531 }
532#else
534 {
535 return ComparisonIndex == Rhs.ComparisonIndex && Number == Rhs.Number;
536 }
538 {
539 return GetTypeHash(Name.ComparisonIndex) + Name.Number;
540 }
541#endif
542};
543
544struct FMemoryImageName;
545
546namespace Freeze
547{
551}
552
558{
559 friend FName;
560
564
568
569 inline bool UEOpEquals(EName Name) const { return UEOpEquals(FMemoryImageName(Name)); }
570
571 FORCEINLINE bool IsNone() const;
572 CORE_API FString ToString() const;
573
574 // The internal structure of FMemoryImageName is private in order to handle UE_FNAME_OUTLINE_NUMBER
575private:
577 FNameEntryId ComparisonIndex;
578#if UE_FNAME_OUTLINE_NUMBER
579 uint32 Dummy = 0; // Dummy to keep the size the same regardless of build configuration, but change the name so trying to use Number is a compile error
580#else // UE_FNAME_OUTLINE_NUMBER
582 uint32 Number = NAME_NO_NUMBER_INTERNAL;
583#endif // UE_FNAME_OUTLINE_NUMBER
584#if WITH_CASE_PRESERVING_NAME
586 FNameEntryId DisplayIndex;
587#endif
588
589public:
590#if UE_FNAME_OUTLINE_NUMBER
591 FORCEINLINE bool UEOpEquals(FMemoryImageName Rhs) const
592 {
593 return ComparisonIndex == Rhs.ComparisonIndex;
594 }
596 {
597 return GetTypeHash(Name.ComparisonIndex);
598 }
599#else
601 {
602 return ComparisonIndex == Rhs.ComparisonIndex && Number == Rhs.Number;
603 }
605 {
606 return GetTypeHash(Name.ComparisonIndex) + Name.Number;
607 }
608#endif
609};
610
616class FName
617{
618public:
619 constexpr static bool bHasIntrusiveUnsetOptionalState = true;
621
622#if UE_FNAME_OUTLINE_NUMBER
623 [[nodiscard]] CORE_API FNameEntryId GetComparisonIndex() const;
624 [[nodiscard]] CORE_API FNameEntryId GetDisplayIndex() const;
625#else // UE_FNAME_OUTLINE_NUMBER
627 {
628 checkName(IsWithinBounds(ComparisonIndex));
629 return ComparisonIndex;
630 }
631
633 {
634 const FNameEntryId Index = GetDisplayIndexFast();
635 checkName(IsWithinBounds(Index));
636 return Index;
637 }
638#endif //UE_FNAME_OUTLINE_NUMBER
639
640#if UE_FNAME_OUTLINE_NUMBER
641 [[nodiscard]] CORE_API int32 GetNumber() const;
642 CORE_API void SetNumber(const int32 NewNumber);
643#else //UE_FNAME_OUTLINE_NUMBER
645 {
646 return Number;
647 }
648
650 {
652 }
653#endif //UE_FNAME_OUTLINE_NUMBER
654
656 [[nodiscard]] CORE_API FString GetPlainNameString() const;
657
659 CORE_API uint32 GetPlainNameString(TCHAR(&OutName)[NAME_SIZE]) const;
660
662 CORE_API void GetPlainANSIString(ANSICHAR(&AnsiName)[NAME_SIZE]) const;
663
665 CORE_API void GetPlainWIDEString(WIDECHAR(&WideName)[NAME_SIZE]) const;
666
667 [[nodiscard]] CORE_API const FNameEntry* GetComparisonNameEntry() const;
668 [[nodiscard]] CORE_API const FNameEntry* GetDisplayNameEntry() const;
669
675 [[nodiscard]] CORE_API FString ToString() const;
676
682 [[nodiscard]] CORE_API FUtf8String ToUtf8String() const;
683
689 CORE_API void ToString(FWideString& Out) const;
690 CORE_API void ToString(FUtf8String& Out) const;
691
697 CORE_API void ToString(FWideStringBuilderBase& Out) const;
698 CORE_API void ToString(FUtf8StringBuilderBase& Out) const;
699
703 [[nodiscard]] CORE_API uint32 GetStringLength() const;
704
708 static constexpr inline uint32 StringBufferSize = NAME_SIZE + 1 + 10; // NAME_SIZE includes null-terminator
709
710private:
716 CORE_API uint32 ToStringInternal(TCHAR* Out, uint32 OutSize) const;
717
718public:
727 "FName::ToString(TCHAR* Out, uint32 OutSize) is dangerous and can lead to buffer overflow if the provided "
728 "buffer is smaller than FName::StringBufferSize, even if the OutSize parameter indicates the buffer is "
729 "smaller than this value. Use the templated ToString() or ToStringTruncate() functions to format the name "
730 "string into a pre-allocated array, or use the allocating ToString() functions that return an FString.")
731 uint32 ToString(TCHAR* Out, uint32 OutSize) const
732 {
733 return ToStringInternal(Out, StringBufferSize);
734 }
735
743 template <uint32 N>
744 uint32 ToString(TCHAR (&Out)[N]) const
745 {
746 UE_STATIC_DEPRECATE(5.6, N < StringBufferSize,
747 "FName::ToString(TCHAR (&Out)[N]) requires a buffer of size of at least FName::StringBufferSize. "
748 "Use ToStringTruncate() if a smaller buffer is required and it is safe for the returned string to be truncated.");
749
750 return ToStringInternal(Out, N);
751 }
752
762 {
763 return ToStringInternal(Out, OutSize);
764 }
765
766 template <uint32 N>
768 {
769 static_assert(N > 0, "Out buffer must have at least one element.");
770 return ToStringTruncate(Out, N);
771 }
772
778 CORE_API void AppendString(FWideString& Out) const;
779 CORE_API void AppendString(FUtf8String& Out) const;
780
786 CORE_API void AppendString(FWideStringBuilderBase& Out) const;
787 CORE_API void AppendString(FUtf8StringBuilderBase& Out) const;
788
796 CORE_API bool TryAppendAnsiString(FAnsiStringBuilderBase& Out) const;
797
801 [[nodiscard]] FORCEINLINE bool IsEqual(const FName& Other, const ENameCase CompareMethod = ENameCase::IgnoreCase, const bool bCompareNumber = true) const;
802
804 {
805 return ToUnstableInt() == Other.ToUnstableInt();
806 }
807
810 {
811 return ComparisonIndex == I;
812 }
813
815 [[nodiscard]] FORCEINLINE bool FastLess(const FName& Other) const
816 {
817 return CompareIndexes(Other) < 0;
818 }
819
822 {
823 return Compare(Other) < 0;
824 }
825
827 [[nodiscard]] FORCEINLINE bool IsNone() const
828 {
829#if PLATFORM_64BITS && !WITH_CASE_PRESERVING_NAME
830 return ToUnstableInt() == 0;
831#else
832 return ComparisonIndex.IsNone() && GetNumber() == NAME_NO_NUMBER_INTERNAL;
833#endif
834 }
835
842 [[nodiscard]] bool IsValid() const { return IsWithinBounds(ComparisonIndex); }
843
845 [[nodiscard]] bool IsValidIndexFast() const { return IsValid(); }
846
847
858 CORE_API static bool IsValidXName( const FName InName, const FString& InInvalidChars, FText* OutReason = nullptr, const FText* InErrorCtx = nullptr );
859 CORE_API static bool IsValidXName( const TCHAR* InName, const FString& InInvalidChars, FText* OutReason = nullptr, const FText* InErrorCtx = nullptr );
860 CORE_API static bool IsValidXName( const FString& InName, const FString& InInvalidChars, FText* OutReason = nullptr, const FText* InErrorCtx = nullptr );
861 CORE_API static bool IsValidXName( const FStringView& InName, const FString& InInvalidChars, FText* OutReason = nullptr, const FText* InErrorCtx = nullptr );
862
872 bool IsValidXName( const FString& InInvalidChars, FText* OutReason = nullptr, const FText* InErrorCtx = nullptr ) const
873 {
874 return IsValidXName(*this, InInvalidChars, OutReason, InErrorCtx);
875 }
876 CORE_API bool IsValidXName() const;
877
886 bool IsValidXName( FText& OutReason, const FString& InInvalidChars ) const
887 {
888 return IsValidXName(*this, InInvalidChars, &OutReason);
889 }
890 CORE_API bool IsValidXName( FText& OutReason ) const;
891
899 CORE_API bool IsValidObjectName( FText& OutReason ) const;
900
909 CORE_API bool IsValidGroupName( FText& OutReason, bool bIsGroupName=false ) const;
910
919 [[nodiscard]] CORE_API static FString SanitizeWhitespace(const FString& FNameString);
920
927 [[nodiscard]] CORE_API int32 Compare( const FName& Other ) const;
928
936 {
937 if (int32 ComparisonDiff = ComparisonIndex.CompareFast(Other.ComparisonIndex))
938 {
939 return ComparisonDiff;
940 }
941
942#if UE_FNAME_OUTLINE_NUMBER
943 return 0; // If comparison indices are the same we are the same
944#else //UE_FNAME_OUTLINE_NUMBER
945 return GetNumber() - Other.GetNumber();
946#endif //UE_FNAME_OUTLINE_NUMBER
947 }
948
955
963 : FName(CreateNumberedNameIfNecessary(FNameEntryId::FromEName(Ename), InNumber))
964 {
965 }
966
967
975 : FName(CreateNumberedNameIfNecessary(Other.GetComparisonIndex(), Other.GetDisplayIndex(), InNumber))
976 {
977 }
978
987
988#if WITH_CASE_PRESERVING_NAME
989 [[nodiscard]] CORE_API static FNameEntryId GetComparisonIdFromDisplayId(FNameEntryId DisplayId);
990#else
991 [[nodiscard]] static FNameEntryId GetComparisonIdFromDisplayId(FNameEntryId DisplayId) { return DisplayId; }
992#endif
993
998 {
999#if UE_FNAME_OUTLINE_NUMBER
1000 checkSlow(ResolveEntry(DisplayId)->IsNumbered() == false); // This id should be unnumbered i.e. returned from GetDisplayIndex on an FName.
1001#endif
1002 return FName(GetComparisonIdFromDisplayId(DisplayId), DisplayId, Number);
1003 }
1004
1005#if UE_FNAME_OUTLINE_NUMBER
1007#endif //UE_FNAME_OUTLINE_NUMBER
1008
1012 FORCEINLINE constexpr FName()
1013#if !UE_FNAME_OUTLINE_NUMBER
1015#endif
1016 {
1017 }
1018
1022 explicit constexpr FName(ENoInit)
1023 : ComparisonIndex(NoInit)
1025 , DisplayIndex(NoInit)
1026#endif
1027 {}
1028
1031 : ComparisonIndex(I)
1034#endif
1036 , DisplayIndex(I)
1037#endif
1038 {
1039 }
1040
1041 FORCEINLINE explicit FName(FMinimalName InName);
1042 FORCEINLINE explicit FName(FScriptName InName);
1044
1055 CORE_API FName(const WIDECHAR* Name);
1056 CORE_API FName(const ANSICHAR* Name);
1057 CORE_API FName(const UTF8CHAR* Name);
1058
1059 CORE_API FName(const WIDECHAR* Name, EFindName FindType);
1060 CORE_API FName(const ANSICHAR* Name, EFindName FindType);
1061 CORE_API FName(const UTF8CHAR* Name, EFindName FindType);
1062
1064 CORE_API FName(int32 Len, const WIDECHAR* Name, EFindName FindType=FNAME_Add);
1065 CORE_API FName(int32 Len, const ANSICHAR* Name, EFindName FindType=FNAME_Add);
1066 CORE_API FName(int32 Len, const UTF8CHAR* Name, EFindName FindType=FNAME_Add);
1067
1068 inline explicit FName(TStringView<ANSICHAR> View, EFindName FindType = FNAME_Add)
1069 : FName(NoInit)
1070 {
1071 *this = FName(View.Len(), View.GetData(), FindType);
1072 }
1073 inline explicit FName(TStringView<WIDECHAR> View, EFindName FindType = FNAME_Add)
1074 : FName(NoInit)
1075 {
1076 *this = FName(View.Len(), View.GetData(), FindType);
1077 }
1078 inline explicit FName(TStringView<UTF8CHAR> View, EFindName FindType = FNAME_Add)
1079 : FName(NoInit)
1080 {
1081 *this = FName(View.Len(), View.GetData(), FindType);
1082 }
1083
1084
1098
1100 : FName(NoInit)
1101 {
1102 *this = FName(View.Len(), View.GetData(), InNumber);
1103 }
1105 : FName(NoInit)
1106 {
1107 *this = FName(View.Len(), View.GetData(), InNumber);
1108 }
1110 : FName(NoInit)
1111 {
1112 *this = FName(View.Len(), View.GetData(), InNumber);
1113 }
1114
1125
1132
1133 CORE_API static void DisplayHash( class FOutputDevice& Ar );
1135
1136 CORE_API static void Reserve(uint32 NumBytes, uint32 NumNames);
1137
1141 [[nodiscard]] CORE_API static int64 GetNameEntryMemorySize();
1142
1146 [[nodiscard]] CORE_API static int64 GetNameEntryMemoryEstimatedAvailable();
1147
1151 [[nodiscard]] CORE_API static int64 GetNameTableMemorySize();
1152
1156 [[nodiscard]] CORE_API static int32 GetNumAnsiNames();
1157
1161 [[nodiscard]] CORE_API static int32 GetNumWideNames();
1162
1163#if UE_FNAME_OUTLINE_NUMBER
1168#endif
1169
1170 [[nodiscard]] CORE_API static TArray<const FNameEntry*> DebugDump();
1171
1172 [[nodiscard]] CORE_API static FNameEntry const* GetEntry(EName Ename);
1173 [[nodiscard]] CORE_API static FNameEntry const* GetEntry(FNameEntryId Id);
1174
1175#if UE_TRACE_ENABLED
1177 CORE_API static void TraceNamesOnConnection();
1178#endif
1179
1181
1183 CORE_API static void AutoTest();
1184
1194 [[nodiscard]] CORE_API static FString NameToDisplayString( const FString& InDisplayName, const bool bIsBool );
1195
1201 CORE_API static void AddNameToDisplayStringExemption(const FString& InExemption);
1202 CORE_API static void RemoveNameToDisplayStringExemption(const FString& InExemption);
1203
1205 [[nodiscard]] CORE_API const EName* ToEName() const;
1206
1212 CORE_API static void TearDown();
1213
1215#if UE_FNAME_OUTLINE_NUMBER
1216 [[nodiscard]] FORCEINLINE uint64 ToUnstableInt() const
1217 {
1218 return ComparisonIndex.ToUnstableInt();
1219 }
1220#else
1222 {
1223 static_assert(STRUCT_OFFSET(FName, ComparisonIndex) == 0);
1224 static_assert(STRUCT_OFFSET(FName, Number) == 4);
1225 static_assert((STRUCT_OFFSET(FName, Number) + sizeof(Number)) == sizeof(uint64));
1226
1227 uint64 Out = 0;
1228 FMemory::Memcpy(&Out, this, sizeof(uint64));
1229 return Out;
1230 }
1231#endif
1232
1233private:
1235 FNameEntryId ComparisonIndex;
1236#if !UE_FNAME_OUTLINE_NUMBER
1238 uint32 Number;
1239#endif// ! //UE_FNAME_OUTLINE_NUMBER
1240#if WITH_CASE_PRESERVING_NAME
1242 FNameEntryId DisplayIndex;
1243#endif // WITH_CASE_PRESERVING_NAME
1244
1245 friend const TCHAR* DebugFName(int32);
1246 friend const TCHAR* DebugFName(int32, int32);
1247 friend const TCHAR* DebugFName(FName&);
1248
1249 friend struct FNameHelper;
1250 friend FScriptName NameToScriptName(FName InName);
1251 friend FMinimalName NameToMinimalName(FName InName);
1252 friend FMinimalName::FMinimalName(const FName& Name);
1253 friend FScriptName::FScriptName(const FName& Name);
1255
1256 template <typename StringBufferType>
1257 FORCEINLINE void AppendStringInternal(StringBufferType& Out) const;
1258
1259 FORCEINLINE FNameEntryId GetDisplayIndexFast() const
1260 {
1261#if WITH_CASE_PRESERVING_NAME
1262 return DisplayIndex;
1263#else
1264 return ComparisonIndex;
1265#endif
1266 }
1267
1268 // Accessor for unmodified comparison index when UE_FNAME_OUTLINE_NUMBER is set
1269 [[nodiscard]] FORCEINLINE FNameEntryId GetComparisonIndexInternal() const
1270 {
1271 return ComparisonIndex;
1272 }
1273
1274 // Accessor for unmodified display index when UE_FNAME_OUTLINE_NUMBER is set
1275 [[nodiscard]] FORCEINLINE FNameEntryId GetDisplayIndexInternal() const
1276 {
1277#if WITH_CASE_PRESERVING_NAME
1278 return DisplayIndex;
1279#else // WITH_CASE_PRESERVING_NAME
1280 return ComparisonIndex;
1281#endif // WITH_CASE_PRESERVING_NAME
1282 }
1283
1284 // Resolve the entry directly referred to by LookupId
1285 [[nodiscard]] CORE_API static const FNameEntry* ResolveEntry(FNameEntryId LookupId);
1286 // Recursively resolve through the entry referred to by LookupId to reach the allocated string entry, in the case of UE_FNAME_OUTLINE_NUMBER=1
1287 [[nodiscard]] static const FNameEntry* ResolveEntryRecursive(FNameEntryId LookupId);
1288
1290
1291 // These FNameEntryIds are passed in from user code so they must be non-numbered if Number != NAME_NO_NUMBER_INTERNAL
1292#if UE_FNAME_OUTLINE_NUMBER
1293 [[nodiscard]] CORE_API static FName CreateNumberedName(FNameEntryId ComparisonId, FNameEntryId DisplayId, int32 Number);
1294#endif
1295
1296 [[nodiscard]] FORCEINLINE static FName CreateNumberedNameIfNecessary(FNameEntryId ComparisonId, FNameEntryId DisplayId, int32 Number)
1297 {
1298#if UE_FNAME_OUTLINE_NUMBER
1300 {
1301 // We need to store a new entry in the name table
1302 return CreateNumberedName(ComparisonId, DisplayId, Number);
1303 }
1304 // Otherwise we can just set the index members
1305#endif
1306 FName Out;
1307 Out.ComparisonIndex = ComparisonId;
1308#if WITH_CASE_PRESERVING_NAME
1309 Out.DisplayIndex = DisplayId;
1310#endif
1311#if !UE_FNAME_OUTLINE_NUMBER
1312 Out.Number = Number;
1313#endif
1314 return Out;
1315 }
1316
1317 [[nodiscard]] FORCEINLINE static FName CreateNumberedNameIfNecessary(FNameEntryId ComparisonId, int32 Number)
1318 {
1319 return CreateNumberedNameIfNecessary(ComparisonId, ComparisonId, Number);
1320 }
1321
1322
1323 [[nodiscard]] static bool Equals(FName A, FName B) = delete;
1324 [[nodiscard]] CORE_API static bool Equals(FName A, FAnsiStringView B);
1325 [[nodiscard]] CORE_API static bool Equals(FName A, FWideStringView B);
1326 [[nodiscard]] CORE_API static bool Equals(FName A, const ANSICHAR* B);
1327 [[nodiscard]] CORE_API static bool Equals(FName A, const WIDECHAR* B);
1328
1329 [[nodiscard]] FORCEINLINE static bool Equals(FName A, EName B)
1330 {
1331 // With UE_FNAME_OUTLINE_NUMBER 1, FName == FName(EName) is
1332 // faster than extracting index and number for direct EName comparison.
1333 // return A.GetComparisonIndex() == B && A.GetNumber() == NAME_NO_NUMBER_INTERNAL;
1334 return A == FName(B);
1335 }
1336
1337#if UE_FNAME_OUTLINE_NUMBER
1338 [[nodiscard]] FORCEINLINE static bool Equals(FName A, FMinimalName B)
1339 {
1340 return A.GetComparisonIndexInternal() == B.Index;
1341 }
1342 [[nodiscard]] FORCEINLINE static bool Equals(FName A, FScriptName B)
1343 {
1344 return A.GetComparisonIndexInternal() == B.ComparisonIndex;
1345 }
1347 {
1348 return A.GetComparisonIndexInternal() == B.ComparisonIndex;
1349 }
1351 {
1352 return GetTypeHash(Name.GetComparisonIndexInternal());
1353 }
1354#else
1355 [[nodiscard]] FORCEINLINE static bool Equals(FName A, FMinimalName B)
1356 {
1357 return A.GetComparisonIndex() == B.Index && A.GetNumber() == B.Number;
1358 }
1359 [[nodiscard]] FORCEINLINE static bool Equals(FName A, FScriptName B)
1360 {
1361 return A.GetComparisonIndex() == B.ComparisonIndex && A.GetNumber() == B.Number;
1362 }
1364 {
1365 return A.GetComparisonIndex() == B.ComparisonIndex && A.GetNumber() == B.Number;
1366 }
1368 {
1369 return GetTypeHash(Name.GetComparisonIndex()) + Name.GetNumber();
1370 }
1371#endif
1372
1373public:
1374 template <typename T>
1375 [[nodiscard]] FORCEINLINE auto UEOpEquals(T Rhs) const -> decltype(FName::Equals(*this, Rhs))
1376 {
1377 return FName::Equals(*this, Rhs);
1378 }
1379};
1380
1381template<> struct TIsZeroConstructType<class FName> { enum { Value = true }; };
1383
1384namespace Freeze
1385{
1386 // These structures mirror the layout of FMemoryImageName depending on the value of WITH_CASE_PRESERVING_NAME
1387 // for use in memory image writing/unfreezing
1388 template<bool bCasePreserving>
1390
1391 template<>
1393 {
1394 FNameEntryId ComparisonIndex;
1396 };
1397
1398 template<>
1399 struct TMemoryImageNameLayout<true> : public TMemoryImageNameLayout<false>
1400 {
1401 FNameEntryId DisplayIndex;
1402 };
1403
1404 CORE_API void ApplyMemoryImageNamePatch(void* NameDst, const FMemoryImageName& Name, const FPlatformTypeLayoutParameters& LayoutParams);
1405
1406 CORE_API uint32 IntrinsicAppendHash(const FMemoryImageName* DummyObject, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher);
1407 CORE_API void IntrinsicWriteMemoryImage(FMemoryImageWriter& Writer, const FMemoryImageName& Object, const FTypeLayoutDesc&);
1408 CORE_API uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent& Context, const FMemoryImageName& Object, void* OutDst);
1409 CORE_API void IntrinsicWriteMemoryImage(FMemoryImageWriter& Writer, const FScriptName& Object, const FTypeLayoutDesc&);
1410}
1411
1413{
1414 // The structure must match the layout of Freeze::TMemoryImageNameLayout for the matching value of WITH_CASE_PRESERVING_NAME
1415 static_assert(sizeof(FMemoryImageName) == sizeof(Freeze::TMemoryImageNameLayout<WITH_CASE_PRESERVING_NAME>));
1416 static_assert(STRUCT_OFFSET(FMemoryImageName, ComparisonIndex) == STRUCT_OFFSET(Freeze::TMemoryImageNameLayout<WITH_CASE_PRESERVING_NAME>, ComparisonIndex));
1417#if UE_FNAME_OUTLINE_NUMBER
1418 static_assert(STRUCT_OFFSET(FMemoryImageName, Dummy) == STRUCT_OFFSET(Freeze::TMemoryImageNameLayout<WITH_CASE_PRESERVING_NAME>, NumberOrDummy));
1419#else
1420 static_assert(STRUCT_OFFSET(FMemoryImageName, Number) == STRUCT_OFFSET(Freeze::TMemoryImageNameLayout<WITH_CASE_PRESERVING_NAME>, NumberOrDummy));
1421#endif
1422#if WITH_CASE_PRESERVING_NAME
1423 static_assert(STRUCT_OFFSET(FMemoryImageName, DisplayIndex) == STRUCT_OFFSET(Freeze::TMemoryImageNameLayout<WITH_CASE_PRESERVING_NAME>, DisplayIndex));
1424#endif
1425
1426}
1427
1432
1435
1436#if UE_FNAME_OUTLINE_NUMBER
1437
1439 : ComparisonIndex(InName.Index)
1441 , DisplayIndex(InName.Index)
1442#endif
1443{
1444}
1445
1447 : ComparisonIndex(InName.ComparisonIndex)
1449 , DisplayIndex(InName.DisplayIndex)
1450#endif
1451{
1452
1453}
1454
1456 : ComparisonIndex(InName.ComparisonIndex)
1458 , DisplayIndex(InName.DisplayIndex)
1459#endif
1460{
1461}
1462
1464 : Index(Name.GetComparisonIndexInternal())
1465{
1466}
1467
1469 : ComparisonIndex(Name.GetComparisonIndexInternal())
1471 , DisplayIndex(Name.GetDisplayIndexInternal())
1472#endif
1473{
1474}
1475
1477 : ComparisonIndex(Name.GetComparisonIndexInternal())
1479 , DisplayIndex(Name.GetDisplayIndexInternal())
1480#endif
1481{
1482}
1483
1485{
1486 return Index.IsNone();
1487}
1488
1490{
1491 return Index < Rhs.Index;
1492}
1493
1495{
1496 return ComparisonIndex.IsNone();
1497}
1498
1500{
1501 return ComparisonIndex.IsNone();
1502}
1503
1504FORCEINLINE bool FName::IsEqual(const FName& Rhs, const ENameCase CompareMethod /*= ENameCase::IgnoreCase*/, const bool bCompareNumber /*= true*/) const
1505{
1506 return bCompareNumber ?
1507 (CompareMethod == ENameCase::IgnoreCase ? GetComparisonIndexInternal() == Rhs.GetComparisonIndexInternal() : GetDisplayIndexInternal() == Rhs.GetDisplayIndexInternal()) : // Unresolved indices include the number, are stored in instances
1508 (CompareMethod == ENameCase::IgnoreCase ? GetComparisonIndex() == Rhs.GetComparisonIndex() : GetDisplayIndex() == Rhs.GetDisplayIndex()); // Resolved indices, have to hit the name table
1509}
1510
1511#else // UE_FNAME_OUTLINE_NUMBER
1512
1514 : ComparisonIndex(InName.Index)
1515 , Number(InName.Number)
1517 , DisplayIndex(InName.Index)
1518#endif
1519{
1520}
1521
1523 : ComparisonIndex(InName.ComparisonIndex)
1524 , Number(InName.Number)
1526 , DisplayIndex(InName.DisplayIndex)
1527#endif
1528{
1529}
1530
1532 : ComparisonIndex(InName.ComparisonIndex)
1533 , Number(InName.Number)
1535 , DisplayIndex(InName.DisplayIndex)
1536#endif
1537{
1538}
1539
1541 : Index(Name.GetComparisonIndexInternal())
1542 , Number(Name.GetNumber())
1543{
1544}
1545
1547 : ComparisonIndex(Name.GetComparisonIndexInternal())
1549 , DisplayIndex(Name.GetDisplayIndexInternal())
1550#endif
1551 , Number(Name.GetNumber())
1552{
1553}
1554
1556 : ComparisonIndex(Name.GetComparisonIndex())
1557 , Number(Name.GetNumber())
1559 , DisplayIndex(Name.GetDisplayIndex())
1560#endif
1561{
1562}
1563
1565{
1566 return Index.IsNone() && Number == NAME_NO_NUMBER_INTERNAL;
1567}
1568
1570{
1571 return Index == Rhs.Index ? Number < Rhs.Number : Index < Rhs.Index;
1572}
1573
1575{
1576 return ComparisonIndex.IsNone() && Number == NAME_NO_NUMBER_INTERNAL;
1577}
1578
1580{
1581 return ComparisonIndex.IsNone() && Number == NAME_NO_NUMBER_INTERNAL;
1582}
1583
1584
1585FORCEINLINE bool FName::IsEqual(const FName& Rhs, const ENameCase CompareMethod /*= ENameCase::IgnoreCase*/, const bool bCompareNumber /*= true*/) const
1586{
1587 return ((CompareMethod == ENameCase::IgnoreCase) ? GetComparisonIndex() == Rhs.GetComparisonIndex() : GetDisplayIndexFast() == Rhs.GetDisplayIndexFast())
1588 && (!bCompareNumber || GetNumber() == Rhs.GetNumber());
1589}
1590#endif // UE_FNAME_OUTLINE_NUMBER
1591
1593{
1594 return FName(InName);
1595}
1596
1598{
1599 return FName(InName);
1600}
1601
1603{
1604 return FMinimalName(InName);
1605}
1606
1608{
1609 return FScriptName(InName);
1610}
1611
1612CORE_API FString LexToString(const FName& Name);
1613
1615{
1616 Name = FName(Str);
1617}
1618
1620{
1621 Name.AppendString(Builder);
1622 return Builder;
1623}
1624
1626{
1627 Name.AppendString(Builder);
1628 return Builder;
1629}
1630
1633
1635template <> struct TIsPODType<FName> { enum { Value = true }; };
1636
1639{
1640 FORCEINLINE bool operator()(const FName& A, const FName& B) const
1641 {
1642 return A.CompareIndexes(B) < 0;
1643 }
1644
1646 {
1647 return A.FastLess(B);
1648 }
1649};
1650
1653{
1654 FORCEINLINE bool operator()(const FName& A, const FName& B) const
1655 {
1656 return A.Compare(B) < 0;
1657 }
1658
1660 {
1661 return A.LexicalLess(B);
1662 }
1663};
1664
1666{
1669private:
1670 static constexpr uint32 EntryStride = alignof(FNameEntry);
1671 static constexpr uint32 OffsetBits = 16;
1672 static constexpr uint32 BlockBits = 13;
1673 static constexpr uint32 OffsetMask = (1 << OffsetBits) - 1;
1674 static constexpr uint32 UnusedMask = UINT32_MAX << BlockBits << OffsetBits;
1675 static constexpr uint32 MaxLength = NAME_SIZE;
1676};
1677
1680{
1681 // NOTE: Numeric values are used for comparison in UEOpEquals.
1682 enum class ELiteralType : uint8
1683 {
1684 None = 0,
1685 AnsiLiteral = 1,
1686 Utf8Literal = 2,
1687 WideLiteral = 3,
1688 };
1689
1690public:
1691 constexpr FLazyName() = default;
1692
1694 template <int N>
1695 constexpr FLazyName(const ANSICHAR (&Literal)[N])
1696 : Either{.AnsiLiteral = Literal}
1697 , Number(ParseNumber(Literal, N - 1))
1698 , LiteralType(ELiteralType::AnsiLiteral)
1699 {
1700 }
1701
1703 template <int N>
1704 constexpr FLazyName(const UTF8CHAR (&Literal)[N])
1705 : Either{.Utf8Literal = Literal}
1706 , Number(ParseNumber(Literal, N - 1))
1707 , LiteralType(ELiteralType::Utf8Literal)
1708 {
1709 }
1710
1712 template <int N>
1713 constexpr FLazyName(const WIDECHAR (&Literal)[N])
1714 : Either{.WideLiteral = Literal}
1715 , Number(ParseNumber(Literal, N - 1))
1716 , LiteralType(ELiteralType::WideLiteral)
1717 {
1718 }
1719
1721 : Either{.PackedName = FLiteralOrName::PackName(Name.GetComparisonIndex(), Name.GetDisplayIndex())}
1722 , Number(Name.GetNumber())
1723 , LiteralType(ELiteralType::None)
1724 {
1725 }
1726
1727 UE_REWRITE operator FName() const
1728 {
1729 return Resolve();
1730 }
1731
1732 CORE_API FName Resolve() const;
1733
1734 CORE_API FString ToString() const;
1736
1737private:
1738 union FLiteralOrName
1739 {
1740 // NOTE: This uses the high bit for the flag. This may be an issue in the future if the high byte
1741 // of an address starts being used for features like hardware ASan.
1742 static constexpr uint64 IsNameFlag = uint64(1) << (sizeof(uint64) * 8 - 1);
1743 static constexpr uint32 DisplayIdShift = 32;
1744
1745 const ANSICHAR* AnsiLiteral;
1746 const UTF8CHAR* Utf8Literal;
1747 const WIDECHAR* WideLiteral;
1748 mutable uint64 PackedName = 0;
1749
1750 static constexpr uint64 PackName(FNameEntryId ComparisonId, FNameEntryId DisplayId)
1751 {
1752 // FNameEntryId fits in 31 bits -> (DisplayId & IsNameFlag) != 0 -> IsName() == true.
1753 return IsNameFlag | ComparisonId.ToUnstableInt() |
1754 (WITH_CASE_PRESERVING_NAME ? (uint64(DisplayId.ToUnstableInt()) << DisplayIdShift) : 0);
1755 }
1756
1757 constexpr bool IsName() const
1758 {
1759 return !!(PackedName & IsNameFlag);
1760 }
1761
1762 inline FNameEntryId GetComparisonId() const
1763 {
1764 return FNameEntryId::FromUnstableInt(static_cast<uint32>(PackedName));
1765 }
1766
1767 inline FNameEntryId GetDisplayId() const
1768 {
1769#if WITH_CASE_PRESERVING_NAME
1770 return FNameEntryId::FromUnstableInt(static_cast<uint32>((PackedName & ~IsNameFlag) >> DisplayIdShift));
1771#else
1772 return GetComparisonId();
1773#endif
1774 }
1775 };
1776
1777 FLiteralOrName Either;
1779 ELiteralType LiteralType = ELiteralType::None;
1780
1781 // Parse the number at compile time when possible to avoid runtime initialization overhead.
1782 // Number must be stored upon construction to allow Resolve() to convert a literal
1783 // to a name without synchronization. If Number had to be written at the same time
1784 // it would require synchronization.
1785 template <typename CharType>
1786 UE_REWRITE static constexpr uint32 ParseNumber(const CharType* Literal, int32 Len)
1787 {
1789 {
1790 return UE::Core::Private::ParseNumberFromName(Literal, Len);
1791 }
1792 else
1793 {
1794 return CallParseNumber(Literal, Len);
1795 }
1796 }
1797
1798 template <typename CharType>
1799 CORE_API static uint32 CallParseNumber(const CharType* Literal, int32 Len);
1800
1801public:
1802 bool UEOpEquals(FName Rhs) const
1803 {
1804 // If !Rhs.IsNone(), we have started creating FNames
1805 // and might as well resolve and cache Lhs
1806 if (Either.IsName() || !Rhs.IsNone())
1807 {
1808 return Rhs == Resolve();
1809 }
1810 else if (LiteralType == ELiteralType::AnsiLiteral)
1811 {
1812 return Rhs == Either.AnsiLiteral;
1813 }
1814 else if (LiteralType == ELiteralType::Utf8Literal)
1815 {
1816 return Rhs == Either.Utf8Literal;
1817 }
1818 else
1819 {
1820 return Rhs == Either.WideLiteral;
1821 }
1822 }
1823
1824 CORE_API bool UEOpEquals(const FLazyName& Rhs) const;
1825
1827 {
1828 return GetTypeHash(Name.Resolve());
1829 }
1830};
1831
1832// Ordering operators for FName are deliberately disabled as there is no correct default.
1833// Users should use the following to select the desired behavior:
1834//
1835// Lexicographical comparison:
1836// - Expression: NameA.LexicalLess(NameB)
1837// - Predicate: FNameLexicalLess
1838//
1839// Fast comparison:
1840// - Expression: NameA.FastLess(NameB)
1841// - Predicate: FNameFastLess
1842bool operator<(FName, FName) = delete;
1843bool operator>(FName, FName) = delete;
1844bool operator<=(FName, FName) = delete;
1845bool operator>=(FName, FName) = delete;
1846
1855{
1856public:
1858 explicit FDisplayNameEntryId(FName Name) : FDisplayNameEntryId(Name.GetDisplayIndex(), Name.GetComparisonIndex()) {}
1859 FORCEINLINE FName ToName(uint32 Number) const { return FName(GetComparisonId(), GetDisplayId(), Number); }
1860
1861private:
1862#if WITH_CASE_PRESERVING_NAME
1863 static constexpr uint32 DifferentIdsFlag = 1u << 31;
1864 static constexpr uint32 DisplayIdMask = ~DifferentIdsFlag;
1865
1866 uint32 Value = 0;
1867
1868 FDisplayNameEntryId(FNameEntryId Id, FNameEntryId CmpId) : Value(Id.ToUnstableInt() | (Id != CmpId) * DifferentIdsFlag) {}
1869 FORCEINLINE bool SameIds() const { return (Value & DifferentIdsFlag) == 0; }
1871 FORCEINLINE FNameEntryId GetComparisonId() const { return SameIds() ? GetDisplayId() : FName::GetComparisonIdFromDisplayId(GetDisplayId()); }
1872public:
1873 bool UEOpEquals(FDisplayNameEntryId Rhs) const { return Value == Rhs.Value; }
1874#else
1875 FNameEntryId Id;
1876
1878 FORCEINLINE FNameEntryId GetDisplayId() const { return Id; }
1879 FORCEINLINE FNameEntryId GetComparisonId() const { return Id; }
1880public:
1881 bool UEOpEquals(FDisplayNameEntryId Rhs) const { return Id == Rhs.Id; }
1882#endif
1883 bool UEOpEquals(FNameEntryId Rhs) const { return GetDisplayId() == Rhs; }
1884 [[nodiscard]] friend uint32 GetTypeHash(FDisplayNameEntryId InId) { return GetTypeHash(InId.GetDisplayId()); }
1885
1886public: // Internal functions for batch serialization code - intentionally lacking CORE_API
1888 FNameEntryId ToDisplayId() const;
1889 void SetLoadedComparisonId(FNameEntryId ComparisonId); // Called first
1890#if WITH_CASE_PRESERVING_NAME
1891 void SetLoadedDifferentDisplayId(FNameEntryId DisplayId); // Called second if display id differs
1892 FNameEntryId GetLoadedComparisonId() const; // Get the already loaded comparison id
1893#endif
1894};
1895
1899class FNameBuilder : public TStringBuilder<FName::StringBufferSize>
1900{
1901public:
1902 FNameBuilder() = default;
1903
1904 inline explicit FNameBuilder(const FName InName)
1905 {
1906 InName.AppendString(*this);
1907 }
1908};
1909
1910template <> struct TIsContiguousContainer<FNameBuilder> { static constexpr inline bool Value = true; };
1911
1913class FBlake3;
1914CORE_API void AppendHash(FBlake3& Builder, FName In);
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define UE_STATIC_DEPRECATE(Version, bExpression, Message)
Definition CoreMiscDefines.h:420
ENoInit
Definition CoreMiscDefines.h:158
@ NoInit
Definition CoreMiscDefines.h:158
#define UE_IF_CONSTEVAL
Definition Platform.h:786
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
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::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
#define UE_REWRITE
Definition Platform.h:747
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
FArchive & operator<<(FArchive &Ar, FEnvQueryDebugProfileData::FStep &Data)
Definition EnvQueryTypes.cpp:489
return true
Definition ExternalRpcRegistry.cpp:601
#define DECLARE_INTRINSIC_TYPE_LAYOUT(T)
Definition MemoryLayout.h:760
bool IsEqual(TRangeBound< FFrameNumber > A, TRangeBound< FFrameNumber > B)
Definition MovieSceneTransformTests.cpp:15
CORE_API FString LexToString(const FName &Name)
Definition UnrealNames.cpp:3569
#define NAME_NO_NUMBER_INTERNAL
Definition NameTypes.h:157
CORE_API void AppendHash(FBlake3 &Builder, FName In)
Definition UnrealNames.cpp:3801
ENameCase
Definition NameTypes.h:194
FORCEINLINE FMinimalName NameToMinimalName(FName InName)
Definition NameTypes.h:1602
@ NAME_SIZE
Definition NameTypes.h:57
#define WITH_CASE_PRESERVING_NAME
Definition NameTypes.h:33
#define UE_FNAME_OUTLINE_NUMBER
Definition NameTypes.h:39
ELinkerNameTableConstructor
Definition NameTypes.h:199
@ ENAME_LinkerConstructor
Definition NameTypes.h:199
FORCEINLINE void LexFromString(FName &Name, const TCHAR *Str)
Definition NameTypes.h:1614
#define NAME_EXTERNAL_TO_INTERNAL(x)
Definition NameTypes.h:161
bool operator<(FName, FName)=delete
EFindName
Definition NameTypes.h:203
@ FNAME_Find
Definition NameTypes.h:209
@ FNAME_Add
Definition NameTypes.h:212
bool operator<=(FName, FName)=delete
FORCEINLINE FName MinimalNameToName(FMinimalName InName)
Definition NameTypes.h:1592
FORCEINLINE FScriptName NameToScriptName(FName InName)
Definition NameTypes.h:1607
bool operator>=(FName, FName)=delete
FNameEntryId NAME_INDEX
Definition NameTypes.h:150
#define checkName
Definition NameTypes.h:152
FORCEINLINE FName ScriptNameToName(FScriptName InName)
Definition NameTypes.h:1597
bool operator>(FName, FName)=delete
FWideStringBuilderBase & operator<<(FWideStringBuilderBase &Builder, const FName &Name)
Definition NameTypes.h:1619
const bool
Definition NetworkReplayStreaming.h:178
#define MAX_int32
Definition NumericLimits.h:25
const TCHAR * DebugFName(FNameEntryId Index)
Definition UnrealNames.cpp:2317
EName
Definition UnrealNames.h:16
#define STRUCT_OFFSET(struc, member)
Definition UnrealTemplate.h:218
#define Expose_TNameOf(type)
Definition UnrealTypeTraits.h:199
if(Failed) console_printf("Failed.\n")
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition Blake3.h:94
Definition NameTypes.h:1855
FDisplayNameEntryId(FName Name)
Definition NameTypes.h:1858
bool UEOpEquals(FDisplayNameEntryId Rhs) const
Definition NameTypes.h:1881
FORCEINLINE FName ToName(uint32 Number) const
Definition NameTypes.h:1859
FDisplayNameEntryId()
Definition NameTypes.h:1857
static FDisplayNameEntryId FromComparisonId(FNameEntryId ComparisonId)
Definition UnrealNames.cpp:4618
FNameEntryId ToDisplayId() const
Definition UnrealNames.cpp:4613
bool UEOpEquals(FNameEntryId Rhs) const
Definition NameTypes.h:1883
friend uint32 GetTypeHash(FDisplayNameEntryId InId)
Definition NameTypes.h:1884
void SetLoadedComparisonId(FNameEntryId ComparisonId)
Definition UnrealNames.cpp:4646
Definition NameTypes.h:1680
friend FORCEINLINE uint32 GetTypeHash(FLazyName Name)
Definition NameTypes.h:1826
constexpr FLazyName(const ANSICHAR(&Literal)[N])
Definition NameTypes.h:1695
FLazyName(FName Name)
Definition NameTypes.h:1720
constexpr FLazyName(const WIDECHAR(&Literal)[N])
Definition NameTypes.h:1713
constexpr FLazyName(const UTF8CHAR(&Literal)[N])
Definition NameTypes.h:1704
bool UEOpEquals(FName Rhs) const
Definition NameTypes.h:1802
CORE_API FString ToString() const
Definition UnrealNames.cpp:4544
constexpr FLazyName()=default
CORE_API FName Resolve() const
Definition UnrealNames.cpp:4499
CORE_API FUtf8String ToUtf8String() const
Definition UnrealNames.cpp:4549
Definition MemoryImageWriter.h:14
Definition MemoryImageWriter.h:78
Definition NameTypes.h:1900
FNameBuilder()=default
FNameBuilder(const FName InName)
Definition NameTypes.h:1904
Definition UnrealNames.cpp:521
Definition UnrealNames.cpp:1192
Definition UnrealNames.cpp:1722
Definition NameTypes.h:617
FORCEINLINE FName(FNameEntryId InComparisonIndex, FNameEntryId InDisplayIndex, int32 InNumber)
Definition NameTypes.h:983
FName(TStringView< UTF8CHAR > View, int32 InNumber)
Definition NameTypes.h:1109
FORCEINLINE FName(FName Other, int32 InNumber)
Definition NameTypes.h:974
FName(FIntrusiveUnsetOptionalState I)
Definition NameTypes.h:1030
FORCEINLINE int32 CompareIndexes(const FName &Other) const
Definition NameTypes.h:935
friend FORCEINLINE uint32 GetTypeHash(FName Name)
Definition NameTypes.h:1367
FORCEINLINE bool IsEqual(const FName &Other, const ENameCase CompareMethod=ENameCase::IgnoreCase, const bool bCompareNumber=true) const
Definition NameTypes.h:1585
uint32 ToStringTruncate(TCHAR *Out, uint32 OutSize) const
Definition NameTypes.h:761
bool IsValidXName(const FString &InInvalidChars, FText *OutReason=nullptr, const FText *InErrorCtx=nullptr) const
Definition NameTypes.h:872
uint32 ToString(TCHAR(&Out)[N]) const
Definition NameTypes.h:744
FORCEINLINE void SetNumber(const int32 NewNumber)
Definition NameTypes.h:649
bool IsValidXName(FText &OutReason, const FString &InInvalidChars) const
Definition NameTypes.h:886
static FName CreateFromDisplayId(FNameEntryId DisplayId, int32 Number)
Definition NameTypes.h:997
static FNameEntryId GetComparisonIdFromDisplayId(FNameEntryId DisplayId)
Definition NameTypes.h:991
FName(TStringView< ANSICHAR > View, EFindName FindType=FNAME_Add)
Definition NameTypes.h:1068
constexpr FName(ENoInit)
Definition NameTypes.h:1022
FORCEINLINE FNameEntryId GetDisplayIndex() const
Definition NameTypes.h:632
FName(TStringView< WIDECHAR > View, EFindName FindType=FNAME_Add)
Definition NameTypes.h:1073
bool IsValidIndexFast() const
Definition NameTypes.h:845
FORCEINLINE auto UEOpEquals(T Rhs) const -> decltype(FName::Equals(*this, Rhs))
Definition NameTypes.h:1375
FORCEINLINE FName(EName Ename, int32 InNumber)
Definition NameTypes.h:962
bool UEOpEquals(FIntrusiveUnsetOptionalState I) const
Definition NameTypes.h:809
uint32 ToStringTruncate(TCHAR(&Out)[N]) const
Definition NameTypes.h:767
FORCEINLINE FNameEntryId GetComparisonIndex() const
Definition NameTypes.h:626
friend const TCHAR * DebugFName(int32)
FORCEINLINE bool LexicalLess(const FName &Other) const
Definition NameTypes.h:821
FORCEINLINE bool IsNone() const
Definition NameTypes.h:827
FORCEINLINE uint64 ToUnstableInt() const
Definition NameTypes.h:1221
FORCEINLINE bool FastLess(const FName &Other) const
Definition NameTypes.h:815
FName(TStringView< UTF8CHAR > View, EFindName FindType=FNAME_Add)
Definition NameTypes.h:1078
bool IsValid() const
Definition NameTypes.h:842
FORCEINLINE constexpr FName()
Definition NameTypes.h:1012
FName(TStringView< WIDECHAR > View, int32 InNumber)
Definition NameTypes.h:1104
CORE_API void AppendString(FWideString &Out) const
Definition UnrealNames.cpp:3717
UE_DEPRECATED(5.6, "FName::ToString(TCHAR* Out, uint32 OutSize) is dangerous and can lead to buffer overflow if the provided " "buffer is smaller than FName::StringBufferSize, even if the OutSize parameter indicates the buffer is " "smaller than this value. Use the templated ToString() or ToStringTruncate() functions to format the name " "string into a pre-allocated array, or use the allocating ToString() functions that return an FString.") uint32 ToString(TCHAR *Out
FORCEINLINE int32 GetNumber() const
Definition NameTypes.h:644
FORCEINLINE bool UEOpEquals(FName Other) const
Definition NameTypes.h:803
FName(TStringView< ANSICHAR > View, int32 InNumber)
Definition NameTypes.h:1099
FORCEINLINE FName(EName Ename)
Definition NameTypes.h:954
Definition OutputDevice.h:133
Definition SecureHash.h:314
Definition Text.h:385
Definition Array.h:670
Definition StringBuilder.h:79
Definition StringBuilder.h:509
constexpr int32 Len() const
Definition StringView.h:174
constexpr const CharType * GetData() const
Definition StringView.h:160
@ Number
Definition SlateWrapperTypes.h:176
uint32 GetTypeHash(const FKey &Key)
Definition BlackboardKey.h:35
const TCHAR * Name
Definition OodleDataCompression.cpp:30
Definition Array.h:3955
UE_NODEBUG void IntrinsicWriteMemoryImage(FMemoryImageWriter &Writer, const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &)
Definition Array.h:3957
CORE_API void ApplyMemoryImageNamePatch(void *NameDst, const FMemoryImageName &Name, const FPlatformTypeLayoutParameters &LayoutParams)
Definition UnrealNames.cpp:5771
UE_NODEBUG uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent &Context, const TArray< T, AllocatorType > &Object, void *OutDst)
Definition Array.h:3963
implementation
Definition PlayInEditorLoadingScope.h:8
bool IsWithinBounds(FComponentBounds Lhs, FComponentBounds Rhs)
Definition ShaderTypes.h:53
FORCEINLINE UE_STRING_CLASS RhsType && Rhs
Definition String.cpp.inl:718
@ Id
Definition Protocol0.h:17
@ false
Definition radaudio_common.h:23
U16 Index
Definition radfft.cpp:71
Definition NameTypes.h:65
Definition IntrusiveUnsetOptionalState.h:71
Definition NameTypes.h:558
bool UEOpEquals(EName Name) const
Definition NameTypes.h:569
FORCEINLINE bool IsNone() const
Definition NameTypes.h:1579
FMemoryImageName()
Definition NameTypes.h:1412
FORCEINLINE bool UEOpEquals(FMemoryImageName Rhs) const
Definition NameTypes.h:600
friend FName
Definition NameTypes.h:559
friend FORCEINLINE uint32 GetTypeHash(FMemoryImageName Name)
Definition NameTypes.h:604
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition NameTypes.h:439
FMinimalName(EName N)
Definition NameTypes.h:444
friend FORCEINLINE uint32 GetTypeHash(FMinimalName Name)
Definition NameTypes.h:476
friend FName
Definition NameTypes.h:440
FORCEINLINE bool UEOpLessThan(FMinimalName Rhs) const
Definition NameTypes.h:1569
FORCEINLINE bool IsNone() const
Definition NameTypes.h:1564
FORCEINLINE bool UEOpEquals(FMinimalName Rhs) const
Definition NameTypes.h:472
FMinimalName()
Definition NameTypes.h:442
Definition NameTypes.h:1666
CORE_API uint8 ** GetBlocks()
Definition UnrealNames.cpp:5746
Definition NameTypes.h:264
static constexpr uint32 ProbeHashBits
Definition NameTypes.h:269
uint16 LowercaseProbeHash
Definition NameTypes.h:270
uint16 Len
Definition NameTypes.h:271
uint16 bIsWide
Definition NameTypes.h:265
Definition NameTypes.h:69
bool LexicalLess(FNameEntryId Rhs) const
Definition NameTypes.h:85
bool FastLess(FNameEntryId Rhs) const
Definition NameTypes.h:93
constexpr FNameEntryId()
Definition NameTypes.h:74
bool UEOpEquals(EName Ename) const
Definition NameTypes.h:126
bool LexicalSensitiveLess(FNameEntryId Rhs) const
Definition NameTypes.h:89
constexpr FNameEntryId(FIntrusiveUnsetOptionalState)
Definition NameTypes.h:76
static FNameEntryId FromUnstableInt(uint32 UnstableInt)
Definition NameTypes.h:114
bool UEOpLessThan(FNameEntryId Rhs) const
Definition NameTypes.h:96
static FORCEINLINE FNameEntryId FromEName(EName Ename)
Definition NameTypes.h:121
bool UEOpEquals(FIntrusiveUnsetOptionalState) const
Definition NameTypes.h:102
bool UEOpEquals(FNameEntryId Rhs) const
Definition NameTypes.h:99
constexpr bool IsNone() const
Definition NameTypes.h:78
int32 CompareFast(FNameEntryId Rhs) const
Definition NameTypes.h:92
constexpr uint32 ToUnstableInt() const
Definition NameTypes.h:111
constexpr FNameEntryId(ENoInit)
Definition NameTypes.h:75
CORE_API int32 CompareLexical(FNameEntryId Rhs) const
Definition UnrealNames.cpp:2291
CORE_API int32 CompareLexicalSensitive(FNameEntryId Rhs) const
Definition UnrealNames.cpp:2296
static constexpr bool bHasIntrusiveUnsetOptionalState
Definition NameTypes.h:70
CORE_API friend FArchive & operator<<(FArchive &Ar, FNameEntryId &InId)
Definition UnrealNames.cpp:358
friend CORE_API uint32 GetTypeHash(FNameEntryId Id)
Definition UnrealNames.cpp:353
Definition NameTypes.h:387
WIDECHAR const * GetWideName() const
Definition NameTypes.h:415
FNameEntrySerialized(enum ELinkerNameTableConstructor)
Definition NameTypes.h:401
ANSICHAR const * GetAnsiName() const
Definition NameTypes.h:406
friend FArchive & operator<<(FArchive &Ar, FNameEntrySerialized *E)
Definition NameTypes.h:427
Definition NameTypes.h:279
FORCEINLINE int32 GetNameLength() const
Definition NameTypes.h:316
CORE_API void AppendNameToString(FWideString &OutString) const
FORCEINLINE bool IsNumbered() const
Definition NameTypes.h:321
FNumberedData NumberedName
Definition NameTypes.h:303
FORCEINLINE bool IsWide() const
Definition NameTypes.h:315
static constexpr int32 GetDataOffset()
Definition NameTypes.h:362
Definition NameTypes.h:1639
FORCEINLINE bool operator()(const FName &A, const FName &B) const
Definition NameTypes.h:1640
FORCEINLINE bool operator()(FNameEntryId A, FNameEntryId B) const
Definition NameTypes.h:1645
Definition UnrealNames.cpp:3002
Definition NameTypes.h:1653
FORCEINLINE bool operator()(const FName &A, const FName &B) const
Definition NameTypes.h:1654
FORCEINLINE bool operator()(FNameEntryId A, FNameEntryId B) const
Definition NameTypes.h:1659
Definition UnrealNames.cpp:183
Definition UnrealNames.cpp:508
Definition MemoryLayout.h:799
Definition NameTypes.h:491
friend FORCEINLINE uint32 GetTypeHash(FScriptName Name)
Definition NameTypes.h:537
FScriptName(EName Ename)
Definition NameTypes.h:496
FORCEINLINE bool IsNone() const
Definition NameTypes.h:1574
FORCEINLINE bool UEOpEquals(FScriptName Rhs) const
Definition NameTypes.h:533
FScriptName()
Definition NameTypes.h:494
CORE_API FUtf8String ToUtf8String() const
friend FName
Definition NameTypes.h:492
bool UEOpEquals(EName Name) const
Definition NameTypes.h:504
Definition MemoryLayout.h:108
Definition IsContiguousContainer.h:16
static constexpr bool Value
Definition IsContiguousContainer.h:20
Definition IsPODType.h:12
@ Value
Definition IsPODType.h:13
Definition UnrealTypeTraits.h:172
Definition Trace.h:58
Definition UnrealNames.cpp:177