UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
TypeHash.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 "Misc/Crc.h"
8
9#include <stdint.h>
10#include <type_traits>
11
12
13namespace UE
14{
15 namespace Private
16 {
18 {
19 Hash ^= Hash >> 16;
20 Hash *= 0x85ebca6b;
21 Hash ^= Hash >> 13;
22 Hash *= 0xc2b2ae35;
23 Hash ^= Hash >> 16;
24 return Hash;
25 }
26 }
27}
28
36[[nodiscard]] inline constexpr uint32 HashCombine(uint32 A, uint32 C)
37{
38 uint32 B = 0x9e3779b9;
39 A += B;
40
41 A -= B; A -= C; A ^= (C>>13);
42 B -= C; B -= A; B ^= (A<<8);
43 C -= A; C -= B; C ^= (B>>13);
44 A -= B; A -= C; A ^= (C>>12);
45 B -= C; B -= A; B ^= (A<<16);
46 C -= A; C -= B; C ^= (B>>5);
47 A -= B; A -= C; A ^= (C>>3);
48 B -= C; B -= A; B ^= (A<<10);
49 C -= A; C -= B; C ^= (B>>15);
50
51 return C;
52}
53template <
54 typename... Types
55 UE_REQUIRES((std::is_convertible_v<Types, uint32> && ...))
56>
57[[nodiscard]] inline constexpr uint32 HashCombine(uint32 A, Types... Vals)
58{
59 if constexpr (sizeof...(Types) > 0)
60 {
62 }
63 return A;
64}
65
75{
76 return A ^ (B + 0x9e3779b9 + (A << 6) + (A >> 2));
77}
78template <
79 typename... Types
80 UE_REQUIRES((std::is_convertible_v<Types, uint32> && ...))
81>
82[[nodiscard]] inline constexpr uint32 HashCombineFast(uint32 A, Types... Vals)
83{
84 if constexpr (sizeof...(Types) > 0)
85 {
87 }
88 return A;
89}
90
91[[nodiscard]] inline uint32 PointerHash(const void* Key)
92{
93 // Ignoring the lower 4 bits since they are likely zero anyway.
94 // Higher bits are more significant in 64 bit builds.
95 const UPTRINT PtrInt = reinterpret_cast<UPTRINT>(Key) >> 4;
97}
98
99[[nodiscard]] inline uint32 PointerHash(const void* Key, uint32 C)
100{
101 // we can use HashCombineFast here because pointers are non-persistent
102 return HashCombineFast(PointerHash(Key), C);
103}
104
105
106//
107// Hash functions for common types.
108//
109// WARNING! GetTypeHash result values are not expected to leave the running process.
110// Do not persist them to disk, send them to another running process or
111// expect them to be consistent across multiple runs.
112//
113
114template <
115 typename ScalarType,
116 std::enable_if_t<std::is_scalar_v<ScalarType> && !std::is_same_v<ScalarType, TCHAR*> && !std::is_same_v<ScalarType, const TCHAR*>>* = nullptr
117>
118[[nodiscard]] inline uint32 GetTypeHash(ScalarType Value)
119{
120 if constexpr (std::is_integral_v<ScalarType>)
121 {
122 if constexpr (sizeof(ScalarType) <= 4)
123 {
124 return Value;
125 }
126 else if constexpr (sizeof(ScalarType) == 8)
127 {
128 return (uint32)Value + ((uint32)(Value >> 32) * 23);
129 }
130 else if constexpr (sizeof(ScalarType) == 16)
131 {
132 const uint64 Low = (uint64)Value;
133 const uint64 High = (uint64)(Value >> 64);
134 return GetTypeHash(Low) ^ GetTypeHash(High);
135 }
136 else
137 {
138 static_assert(sizeof(ScalarType) == 0, "Unsupported integral type");
139 return 0;
140 }
141 }
142 else if constexpr (std::is_floating_point_v<ScalarType>)
143 {
144 if constexpr (std::is_same_v<ScalarType, float>)
145 {
146 return *(uint32*)&Value;
147 }
148 else if constexpr (std::is_same_v<ScalarType, double>)
149 {
150 return GetTypeHash(*(uint64*)&Value);
151 }
152 else
153 {
154 static_assert(sizeof(ScalarType) == 0, "Unsupported floating point type");
155 return 0;
156 }
157 }
158 else if constexpr (std::is_enum_v<ScalarType>)
159 {
160 return GetTypeHash((__underlying_type(ScalarType))Value);
161 }
162 else if constexpr (std::is_pointer_v<ScalarType>)
163 {
164 // Once the TCHAR* deprecations below are removed, we want to prevent accidental string hashing, so this static_assert should be commented back in
165 //static_assert(!TIsCharType<std::remove_pointer_t<ScalarType>>::Value, "Pointers to string types should use a PointerHash() or FCrc::Stricmp_DEPRECATED() call depending on requirements");
166
167 return PointerHash(Value);
168 }
169 else
170 {
171 static_assert(sizeof(ScalarType) == 0, "Unsupported scalar type");
172 return 0;
173 }
174}
175
176template <
177 typename T,
178 uint32 N,
179 std::enable_if_t<!std::is_same_v<const T, const TCHAR>>* = nullptr
180>
181UE_DEPRECATED(all, "Hashing arrays is deprecated - use PointerHash() instead to force a conversion to a pointer or GetArrayHash to hash the array contents")
183{
184 return PointerHash(Array);
185}
186
187template <
188 typename T,
189 std::enable_if_t<std::is_same_v<const T, const TCHAR>>* = nullptr
190>
191UE_DEPRECATED(5.3, "Hashing TCHAR arrays is deprecated - use PointerHash() to force a conversion to a pointer or FCrc::Strihash_DEPRECATED to do a string hash, or use TStringPointerSetKeyFuncs_DEPRECATED or TStringPointerMapKeyFuncs_DEPRECATED as keyfuncs for a TSet or TMap respectively")
193{
194 // Hashing a TCHAR* array differently from a void* is dangerous and is deprecated.
195 // When removing these overloads post-deprecation, comment in the related static_assert in the std::is_pointer_v block of the GetTypeHash overload above.
197}
198
199template <typename T>
201{
202 uint32 Result = PreviousHash;
203 while (Size)
204 {
205 Result = HashCombineFast(Result, GetTypeHash(*Ptr));
206 ++Ptr;
207 --Size;
208 }
209
210 return Result;
211}
212
213// Use this when inside type that has GetTypeHash() (no in-parameters) implemented. It makes GetTypeHash dispatch in global namespace
214template <typename T>
215[[nodiscard]] UE_FORCEINLINE_HINT uint32 GetTypeHashHelper(const T& V) { return static_cast<uint32>(GetTypeHash(V)); }
216
217// Use this when in a scope that has AppendHash to dispatch AppendHash using unqualified lookup.
218template <typename BuilderType, typename ArgType>
219inline void DispatchAppendHash(BuilderType& Builder, const ArgType& Arg)
220{
221 AppendHash(Builder, Arg);
222}
223
224#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_6
225#include "Templates/IsEnum.h"
226#endif
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
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 UE_REQUIRES(...)
Definition Requires.h:86
constexpr uint32 HashCombineFast(uint32 A, uint32 B)
Definition TypeHash.h:74
uint32 PointerHash(const void *Key)
Definition TypeHash.h:91
UE_FORCEINLINE_HINT uint32 GetTypeHashHelper(const T &V)
Definition TypeHash.h:215
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
uint32 GetArrayHash(const T *Ptr, uint64 Size, uint32 PreviousHash=0)
Definition TypeHash.h:200
uint32 GetTypeHash(ScalarType Value)
Definition TypeHash.h:118
void DispatchAppendHash(BuilderType &Builder, const ArgType &Arg)
Definition TypeHash.h:219
void AppendHash(FBlake3 &Builder, FName In)
Definition UnrealNames.cpp:3801
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition OverriddenPropertySet.cpp:45
uint32 MurmurFinalize32(uint32 Hash)
Definition TypeHash.h:17
Definition AdvancedWidgetsModule.cpp:13
static uint32 Strihash_DEPRECATED(const CharType *Data)