UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Map.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
7#include "Algo/Reverse.h"
9#include "Containers/Set.h"
12#include "Misc/StructBuilder.h"
13#include "Templates/Function.h"
14#include "Templates/Sorting.h"
15#include "Templates/Tuple.h"
19#include <type_traits>
20
21#define ExchangeB(A,B) {bool T=A; A=B; B=T;}
22
24template <typename KeyInitType, typename ValueInitType>
26{
27public:
28 std::conditional_t<std::is_rvalue_reference_v<KeyInitType>, KeyInitType&, KeyInitType> Key;
29 std::conditional_t<std::is_rvalue_reference_v<ValueInitType>, ValueInitType&, ValueInitType> Value;
30
32 [[nodiscard]] inline TPairInitializer(KeyInitType InKey, ValueInitType InValue)
33 : Key(InKey)
34 , Value(InValue)
35 {
36 }
37
39 template <typename KeyType, typename ValueType>
41 : Key(Pair.Key)
42 , Value(Pair.Value)
43 {
44 }
45
46 template <typename KeyType, typename ValueType>
51};
52
53
55template <typename KeyInitType>
57{
58public:
59 std::conditional_t<std::is_rvalue_reference_v<KeyInitType>, KeyInitType&, KeyInitType> Key;
60
63 : Key(InKey)
64 {
65 }
66
67 template <typename KeyType, typename ValueType>
69 {
71 }
72};
73
75template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
76struct TDefaultMapKeyFuncs : BaseKeyFuncs<TPair<KeyType, ValueType>, KeyType, bInAllowDuplicateKeys>
77{
80
82 {
83 return Element.Key;
84 }
85
87 {
88 return A == B;
89 }
90
91 template<typename ComparableKey>
93 {
94 return A == B;
95 }
96
98 {
99 return GetTypeHash(Key);
100 }
101
102 template<typename ComparableKey>
104 {
105 return GetTypeHash(Key);
106 }
107};
108
109template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
110struct TDefaultMapHashableKeyFuncs : TDefaultMapKeyFuncs<KeyType, ValueType, bInAllowDuplicateKeys>
111{
112 // Check that the key type is actually hashable
113 //
114 // If this line fails to compile then your key doesn't have
115 // a GetTypeHash() overload.
116 using HashabilityCheck = decltype(GetTypeHash(DeclVal<const KeyType>()));
117};
118
119template <typename AllocatorType, typename InDerivedType = void>
120class TScriptMap;
121
125template <typename T> struct TIsTMap { enum { Value = false }; };
126
127#define UE_TMAP_PREFIX T
128#include "Map.h.inl"
129#undef UE_TMAP_PREFIX
130
131#define UE_TMAP_PREFIX TSparse
132#include "Map.h.inl"
133#undef UE_TMAP_PREFIX
134
135#define UE_TMAP_PREFIX TCompact
136#include "Map.h.inl"
137#undef UE_TMAP_PREFIX
138
140{
141 // int32 KeyOffset; // is always at zero offset from the TPair - not stored here
143
145};
146
147
148// Untyped map type for accessing TMap data, like FScriptArray for TArray.
149// Must have the same memory representation as a TMap.
150template <typename AllocatorType, typename InDerivedType>
152{
153 using DerivedType = std::conditional_t<std::is_void_v<InDerivedType>, TScriptMap, InDerivedType>;
154
155public:
157 {
158 FScriptMapLayout Result;
159
160 // TPair<Key, Value>
162 int32 KeyOffset = PairStruct.AddMember(KeySize, KeyAlignment);
163 Result.ValueOffset = PairStruct.AddMember(ValueSize, ValueAlignment);
164 Result.SetLayout = FScriptSet::GetScriptLayout(PairStruct.GetSize(), PairStruct.GetAlignment());
165
166 checkf(KeyOffset == 0, TEXT("The key inside the TPair is expected to be at the start of the struct"));
167
168 return Result;
169 }
170
172 {
173 }
174
176 // Start - intrusive TOptional<TScriptMap> state //
178 constexpr static bool bHasIntrusiveUnsetOptionalState = true;
180
182 : Pairs(Tag)
183 {
184 }
186 {
187 return Pairs == Tag;
188 }
190 // End - intrusive TOptional<TScriptMap> state //
192
194 {
195 return Pairs.IsValidIndex(Index);
196 }
197
198 [[nodiscard]] bool IsEmpty() const
199 {
200 return Pairs.IsEmpty();
201 }
202
203 [[nodiscard]] int32 Num() const
204 {
205 return Pairs.Num();
206 }
207
209 [[nodiscard]] int32 Max() const
210 {
211 return Pairs.Max();
212 }
213
215 {
216 return Pairs.NumUnchecked();
217 }
218
221 {
222 return Pairs.GetMaxIndex();
223 }
224
226 {
227 return Pairs.GetData(Index, Layout.SetLayout);
228 }
229
230 [[nodiscard]] const void* GetData(int32 Index, const FScriptMapLayout& Layout) const
231 {
232 return Pairs.GetData(Index, Layout.SetLayout);
233 }
234
235 void MoveAssign(DerivedType& Other, const FScriptMapLayout& Layout)
236 {
238
239 checkSlow(this != TypedOther);
240 Empty(0, Layout);
241 Pairs.MoveAssign(TypedOther->Pairs, Layout.SetLayout);
242 }
243
244 void Empty(int32 Slack, const FScriptMapLayout& Layout)
245 {
246 Pairs.Empty(Slack, Layout.SetLayout);
247 }
248
249#if UE_USE_COMPACT_SET_AS_DEFAULT
250 void RemoveAt(int32 Index, const FScriptMapLayout& Layout, TFunctionRef<uint32 (const void*)> GetKeyHash, TFunctionRef<void (void*)> DestructItem)
251 {
252 Pairs.RemoveAt(Index, Layout.SetLayout, GetKeyHash, DestructItem);
253 }
254#else
256 {
257 Pairs.RemoveAt(Index, Layout.SetLayout);
258 }
259#endif
260
268 {
269 return Pairs.AddUninitialized(Layout.SetLayout);
270 }
271
273 {
274 Pairs.RemoveAtUninitialized(Layout.SetLayout, Index);
275 }
276
277 void CommitLastUninitialized(const FScriptMapLayout& Layout, TFunctionRef<uint32 (const void*)> GetKeyHash)
278 {
279 Pairs.CommitLastUninitialized(Layout.SetLayout, GetKeyHash);
280 }
281
282 void CommitAllUninitialized(const FScriptMapLayout& Layout, TFunctionRef<uint32 (const void*)> GetKeyHash)
283 {
284 Pairs.CommitAllUninitialized(Layout.SetLayout, GetKeyHash);
285 }
286
287 void Rehash(const FScriptMapLayout& Layout, TFunctionRef<uint32(const void*)> GetKeyHash)
288 {
289 Pairs.Rehash(Layout.SetLayout, GetKeyHash);
290 }
291
293 [[nodiscard]] int32 FindPairIndex(const void* Key, const FScriptMapLayout& MapLayout, TFunctionRef<uint32(const void*)> GetKeyHash, TFunctionRef<bool(const void*, const void*)> KeyEqualityFn) const
294 {
295 if (Pairs.Num())
296 {
297 // !unsafe! 'Pairs' is mostly treated as a set of TPair<Key, Value>, so anything in
298 // FScriptSet could assume that Key is actually a TPair<Key, Value>, we can hide this
299 // complexity from our caller, at least (so their GetKeyHash/EqualityFn is unaware):
300 return Pairs.FindIndex(
301 Key,
302 MapLayout.SetLayout,
303 GetKeyHash, // We 'know' that the implementation of Find doesn't call GetKeyHash on anything except Key
304 [KeyEqualityFn](const void* InKey, const void* InPair )
305 {
306 return KeyEqualityFn(InKey, (uint8*)InPair);
307 }
308 );
309 }
310
311 return INDEX_NONE;
312 }
313
315 [[nodiscard]] uint8* FindValue(const void* Key, const FScriptMapLayout& MapLayout, TFunctionRef<uint32(const void*)> GetKeyHash, TFunctionRef<bool(const void*, const void*)> KeyEqualityFn)
316 {
317 int32 FoundIndex = FindPairIndex(Key, MapLayout, GetKeyHash, KeyEqualityFn);
318 if (FoundIndex != INDEX_NONE)
319 {
320 uint8* Result = (uint8*)GetData(FoundIndex, MapLayout) + MapLayout.ValueOffset;
321 return Result;
322 }
323
324 return nullptr;
325 }
326
328 void Add(
329 const void* Key,
330 const void* Value,
332 TFunctionRef<uint32(const void*)> GetKeyHash,
333 TFunctionRef<bool(const void*, const void*)> KeyEqualityFn,
336 TFunctionRef<void(void*)> ValueAssignFn,
337 TFunctionRef<void(void*)> DestructKeyFn,
338 TFunctionRef<void(void*)> DestructValueFn)
339 {
340 Pairs.Add(
341 Key,
342 Layout.SetLayout,
343 GetKeyHash,
346 {
347 KeyConstructAndAssignFn((uint8*)NewPair);
348 ValueConstructAndAssignFn((uint8*)NewPair + Layout.ValueOffset);
349 },
351 {
352 DestructValueFn((uint8*)NewPair + Layout.ValueOffset);
353 DestructKeyFn((uint8*)NewPair);
354 }
355 );
356 }
357
366 const void* Key,
368 TFunctionRef<uint32(const void*)> GetKeyHash,
369 TFunctionRef<bool(const void*, const void*)> KeyEqualityFn,
370 TFunctionRef<void(void*, void*)> ConstructPairFn)
371 {
372 const int32 ValueOffset = Layout.ValueOffset;
373 int32 PairIndex = Pairs.FindOrAdd(
374 Key,
375 Layout.SetLayout,
376 GetKeyHash,
378 [ConstructPairFn, ValueOffset](void* NewPair)
379 {
380 ConstructPairFn(NewPair, (uint8*)NewPair + ValueOffset);
381 });
382
383 return (uint8*)Pairs.GetData(PairIndex, Layout.SetLayout) + ValueOffset;
384 }
385
386private:
388
389 // This function isn't intended to be called, just to be compiled to validate the correctness of the type.
390 static void CheckConstraints()
391 {
392 typedef TScriptMap ScriptType;
393 typedef TMap<int32, int8> RealType;
394
395 // Check that the class footprint is the same
396 static_assert(sizeof(ScriptType) == sizeof(RealType), "TScriptMap's size doesn't match TMap");
397 static_assert(alignof(ScriptType) == alignof(RealType), "TScriptMap's alignment doesn't match TMap");
398
399 // Check member sizes
400 static_assert(sizeof(DeclVal<ScriptType>().Pairs) == sizeof(DeclVal<RealType>().Pairs), "TScriptMap's Pairs member size does not match TMap's");
401
402 // Check member offsets
403 static_assert(STRUCT_OFFSET(ScriptType, Pairs) == STRUCT_OFFSET(RealType, Pairs), "TScriptMap's Pairs member offset does not match TMap's");
404 }
405
406public:
407 // These should really be private, because they shouldn't be called, but there's a bunch of code
408 // that needs to be fixed first.
409 TScriptMap(const TScriptMap&) { check(false); }
410 void operator=(const TScriptMap&) { check(false); }
411};
412
413
414template <typename AllocatorType>
415struct TIsZeroConstructType<TScriptMap<AllocatorType>>
416{
417 enum { Value = true };
418};
419
420class FScriptMap : public TScriptMap<FDefaultSetAllocator, FScriptMap>
421{
423
424public:
425 using Super::Super;
426
428 // Start - intrusive TOptional<FScriptMap> state //
432 // End - intrusive TOptional<FScriptMap> state //
434};
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FORCEINLINE constexpr void DestructItem(ElementType *Element)
Definition MemoryOps.h:56
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define STRUCT_OFFSET(struc, member)
Definition UnrealTemplate.h:218
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Map.h:421
Definition StructBuilder.h:14
constexpr int32 AddMember(int32 MemberSize, int32 MemberAlignment)
Definition StructBuilder.h:30
Definition AssetRegistryState.h:50
Definition Map.h:57
std::conditional_t< std::is_rvalue_reference_v< KeyInitType >, KeyInitType &, KeyInitType > Key
Definition Map.h:59
UE_FORCEINLINE_HINT TKeyInitializer(KeyInitType InKey)
Definition Map.h:62
Definition UnrealString.h.inl:34
Definition Map.h:26
TPairInitializer(KeyInitType InKey, ValueInitType InValue)
Definition Map.h:32
std::conditional_t< std::is_rvalue_reference_v< ValueInitType >, ValueInitType &, ValueInitType > Value
Definition Map.h:29
TPairInitializer(const TPair< KeyType, ValueType > &Pair)
Definition Map.h:40
std::conditional_t< std::is_rvalue_reference_v< KeyInitType >, KeyInitType &, KeyInitType > Key
Definition Map.h:28
Definition Map.h:152
TScriptMap(const TScriptMap &)
Definition Map.h:409
bool IsEmpty() const
Definition Map.h:198
void CommitAllUninitialized(const FScriptMapLayout &Layout, TFunctionRef< uint32(const void *)> GetKeyHash)
Definition Map.h:282
void MoveAssign(DerivedType &Other, const FScriptMapLayout &Layout)
Definition Map.h:235
bool IsValidIndex(int32 Index) const
Definition Map.h:193
void * FindOrAdd(const void *Key, const FScriptMapLayout &Layout, TFunctionRef< uint32(const void *)> GetKeyHash, TFunctionRef< bool(const void *, const void *)> KeyEqualityFn, TFunctionRef< void(void *, void *)> ConstructPairFn)
Definition Map.h:365
int32 Max() const
Definition Map.h:209
int32 Num() const
Definition Map.h:203
void RemoveAtUninitialized(const FScriptMapLayout &Layout, int32 Index)
Definition Map.h:272
static constexpr bool bHasIntrusiveUnsetOptionalState
Definition Map.h:178
const void * GetData(int32 Index, const FScriptMapLayout &Layout) const
Definition Map.h:230
void Empty(int32 Slack, const FScriptMapLayout &Layout)
Definition Map.h:244
TScriptMap(FIntrusiveUnsetOptionalState Tag)
Definition Map.h:181
int32 FindPairIndex(const void *Key, const FScriptMapLayout &MapLayout, TFunctionRef< uint32(const void *)> GetKeyHash, TFunctionRef< bool(const void *, const void *)> KeyEqualityFn) const
Definition Map.h:293
void RemoveAt(int32 Index, const FScriptMapLayout &Layout)
Definition Map.h:255
void operator=(const TScriptMap &)
Definition Map.h:410
void Add(const void *Key, const void *Value, const FScriptMapLayout &Layout, TFunctionRef< uint32(const void *)> GetKeyHash, TFunctionRef< bool(const void *, const void *)> KeyEqualityFn, TFunctionRef< void(void *)> KeyConstructAndAssignFn, TFunctionRef< void(void *)> ValueConstructAndAssignFn, TFunctionRef< void(void *)> ValueAssignFn, TFunctionRef< void(void *)> DestructKeyFn, TFunctionRef< void(void *)> DestructValueFn)
Definition Map.h:328
TScriptMap()
Definition Map.h:171
void * GetData(int32 Index, const FScriptMapLayout &Layout)
Definition Map.h:225
int32 NumUnchecked() const
Definition Map.h:214
int32 GetMaxIndex() const
Definition Map.h:220
int32 AddUninitialized(const FScriptMapLayout &Layout)
Definition Map.h:267
void Rehash(const FScriptMapLayout &Layout, TFunctionRef< uint32(const void *)> GetKeyHash)
Definition Map.h:287
uint8 * FindValue(const void *Key, const FScriptMapLayout &MapLayout, TFunctionRef< uint32(const void *)> GetKeyHash, TFunctionRef< bool(const void *, const void *)> KeyEqualityFn)
Definition Map.h:315
void CommitLastUninitialized(const FScriptMapLayout &Layout, TFunctionRef< uint32(const void *)> GetKeyHash)
Definition Map.h:277
bool operator==(FIntrusiveUnsetOptionalState Tag) const
Definition Map.h:185
static constexpr FScriptMapLayout GetScriptLayout(int32 KeySize, int32 KeyAlignment, int32 ValueSize, int32 ValueAlignment)
Definition Map.h:156
Definition ScriptSparseSet.h:26
static constexpr FScriptSparseSetLayout GetScriptLayout(int32 ElementSize, int32 ElementAlignment)
Definition ScriptSparseSet.h:28
U16 Index
Definition radfft.cpp:71
Definition SetUtilities.h:23
Definition IntrusiveUnsetOptionalState.h:71
Definition Map.h:140
FScriptSetLayout SetLayout
Definition Map.h:144
int32 ValueOffset
Definition Map.h:142
Definition ScriptSparseSet.h:13
Definition Map.h:111
decltype(GetTypeHash(DeclVal< const KeyType >())) HashabilityCheck
Definition Map.h:116
Definition Map.h:77
TTypeTraits< KeyType >::ConstPointerType KeyInitType
Definition Map.h:78
static UE_FORCEINLINE_HINT bool Matches(KeyInitType A, ComparableKey B)
Definition Map.h:92
static UE_FORCEINLINE_HINT uint32 GetKeyHash(ComparableKey Key)
Definition Map.h:103
static UE_FORCEINLINE_HINT bool Matches(KeyInitType A, KeyInitType B)
Definition Map.h:86
const TPairInitializer< typename TTypeTraits< KeyType >::ConstInitType, typename TTypeTraits< ValueType >::ConstInitType > & ElementInitType
Definition Map.h:79
static UE_FORCEINLINE_HINT KeyInitType GetSetKey(ElementInitType Element)
Definition Map.h:81
static UE_FORCEINLINE_HINT uint32 GetKeyHash(KeyInitType Key)
Definition Map.h:97
Definition Map.h:125
@ Value
Definition Map.h:125
Definition UnrealTypeTraits.h:172
Definition Tuple.h:652
TCallTraits< T >::ParamType ConstInitType
Definition UnrealTypeTraits.h:336
TCallTraits< T >::ConstPointerType ConstPointerType
Definition UnrealTypeTraits.h:337