UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CompactSet.h.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#ifndef UE_TCOMPACT_SET
4#error "CompactSet.h.inl should only be included after defining UE_TCOMPACT_SET"
5#endif
6
7#include "ContainersFwd.h"
17#include "Templates/TypeHash.h"
19
20#include <initializer_list>
21#include <type_traits>
22
23namespace UE::Core::Private
24{
25 [[noreturn]] CORE_API void OnInvalidSetNum(unsigned long long NewNum);
26}
27
28#define TSETPRIVATEFRIEND PREPROCESSOR_JOIN(UE_TCOMPACT_SET, PrivateFriend)
29
56template<typename InElementType, typename KeyFuncs /*= DefaultKeyFuncs<ElementType>*/, typename Allocator /*= FDefaultSetAllocator*/>
57class alignas(Allocator::template AllocatorAlignment<InElementType>::Value) UE_TCOMPACT_SET : public TCompactSetBase<typename Allocator::template ElementAllocator<sizeof(InElementType)>>
58{
59public:
61 using KeyFuncsType = KeyFuncs;
62
63private:
64 using Super = TCompactSetBase<typename Allocator::template ElementAllocator<sizeof(InElementType)>>;
68 using USizeType = std::make_unsigned_t<SizeType>;
69 using KeyInitType = typename KeyFuncs::KeyInitType;
70 using ElementInitType = typename KeyFuncs::ElementInitType;
71
72 // Required so TScriptCompactSet can validate it's layout matches this type
73 template <typename ScriptAllocator>
74 friend class TScriptCompactSet;
75
76 // Private helper functions to help binding to global functions
77 friend struct TSETPRIVATEFRIEND;
78
80 template<bool bConst>
81 class TBaseIterator
82 {
83 private:
84 using SetType = std::conditional_t<bConst, const UE_TCOMPACT_SET, UE_TCOMPACT_SET>;
85
86 public:
87 using ElementItType = std::conditional_t<bConst, const ElementType, ElementType>;
88
89 [[nodiscard]] UE_FORCEINLINE_HINT TBaseIterator(SetType& InSet)
90 : TBaseIterator(InSet, 0)
91 {
92 }
93
94 [[nodiscard]] inline TBaseIterator(SetType& InSet, SizeType StartIndex)
95 : Set(InSet)
96 , Index(StartIndex)
98 , InitialNum(InSet.Num())
99#endif
100 {
101#if DO_CHECK
102 check(StartIndex >= 0 && StartIndex <= InitialNum);
103#endif
104 }
105
106 [[nodiscard]] UE_FORCEINLINE_HINT ElementItType & operator*() const
107 {
109 }
110
111 [[nodiscard]] UE_FORCEINLINE_HINT ElementItType* operator->() const
112 {
114 }
115
116 UE_FORCEINLINE_HINT TBaseIterator& operator++()
117 {
118#if DO_CHECK
119 const int32 SetNum = Set.Num();
120 checkf(SetNum >= InitialNum, TEXT("Sets/Maps should never have elements removed during iteration outside of Iterator.RemoveCurrent(). InitialNum %d CurrentNum %d"), InitialNum, SetNum);
121#endif
122 ++Index;
123 return *this;
124 }
125
127 [[nodiscard]] UE_FORCEINLINE_HINT explicit operator bool() const
128 {
129 return Set.IsValidId(this->GetId());
130 }
131
132 [[nodiscard]] inline bool operator==(const TBaseIterator& Rhs) const
133 {
134 checkSlow(&Set == &Rhs.Set);
135 return Index == Rhs.Index;
136 }
137
138 [[nodiscard]] UE_FORCEINLINE_HINT bool operator!=(const TBaseIterator& Rhs) const
139 {
140 return !(*this == Rhs);
141 }
142
143 // Accessors.
145 {
147 }
148
149 protected:
150 SetType& Set;
151 SizeType Index;
152#if DO_CHECK
153 SizeType InitialNum;
154#endif
155 };
156
158 template<bool bConst>
159 class TBaseKeyIterator
160 {
161 private:
162 typedef std::conditional_t < bConst, const UE_TCOMPACT_SET, UE_TCOMPACT_SET > SetType;
163 typedef std::conditional_t < bConst, const ElementType, ElementType > ItElementType;
164 typedef typename TTypeTraits<typename KeyFuncs::KeyType>::ConstPointerType ReferenceOrValueType;
165
166 public:
167 using KeyArgumentType = std::conditional_t <
168 std::is_reference_v<ReferenceOrValueType> ,
170 KeyInitType
171 >;
172
174 [[nodiscard]] inline TBaseKeyIterator(SetType& InSet, KeyArgumentType InKey)
175 : Set (InSet)
176 , Key (InKey)
177 , HashTable(InSet.Num() ? Set.GetConstHashTableView() : FConstCompactHashTableView())
178 , NextIndex(InSet.Num() ? HashTable.GetFirst(KeyFuncs::GetKeyHash(Key)) : INDEX_NONE)
180 , InitialNum(InSet.Num())
181#endif
182 {
183 ++(*this);
184 }
185
187 inline TBaseKeyIterator& operator++()
188 {
189 const int32 SetNum = Set.Num();
190
191 // Note: Adding new elements is safe, however they will be guaranteed to be missed by the current iteration
192#if DO_CHECK
193 checkf(SetNum >= InitialNum, TEXT("Sets/Maps should never have elements removed during iteration outside of Iterator.RemoveCurrent(). InitialNum %d CurrentNum %d"), InitialNum, SetNum);
194#endif
195
196 Index = NextIndex;
197
198 while (Index != INDEX_NONE)
199 {
200 NextIndex = HashTable.GetNext(Index, SetNum);
201 checkSlow(Index != NextIndex);
202
203 if (KeyFuncs::Matches(KeyFuncs::GetSetKey(Set[GetId()]), Key))
204 {
205 break;
206 }
207
208 Index = NextIndex;
209 }
210
211 return *this;
212 }
213
215 [[nodiscard]] UE_FORCEINLINE_HINT explicit operator bool() const
216 {
217 return Index != INDEX_NONE;
218 }
219
220 // Accessors.
222 {
223 return FSetElementId::FromInteger(this->Index);
224 }
225
226 [[nodiscard]] UE_FORCEINLINE_HINT ItElementType* operator->() const
227 {
228 return &Set[GetId()];
229 }
230
231 [[nodiscard]] UE_FORCEINLINE_HINT ItElementType& operator*() const
232 {
233 return Set[GetId()];
234 }
235
236 protected:
237 SetType& Set;
238 ReferenceOrValueType Key;
240 SizeType Index;
241 SizeType NextIndex;
242
243#if DO_CHECK
244 SizeType InitialNum;
245#endif
246 };
247
248public:
249
251 using TConstIterator = TBaseIterator<true>;
252
254 class TIterator : public TBaseIterator<false>
255 {
256 private:
257 using Super = TBaseIterator<false>;
258
259 public:
260 using Super::Super;
261
263 inline void RemoveCurrent()
264 {
265 this->Set.Remove(this->GetId());
266 --this->Index;
267#if DO_CHECK
268 --this->InitialNum;
269#endif
270 }
271 };
272
274 using TConstKeyIterator = TBaseKeyIterator<true>;
275
277 class TKeyIterator : public TBaseKeyIterator<false>
278 {
279 private:
280 using Super = TBaseKeyIterator<false>;
281
282 public:
283 using KeyArgumentType = typename Super::KeyArgumentType;
284 using Super::Super;
285
287 inline void RemoveCurrent()
288 {
289 this->Set.Remove(this->GetId());
290#if DO_CHECK
291 --this->InitialNum;
292#endif
293
294 // If the next element was the last in the set then it will get remapped to the current index, so fix that up
295 if (this->NextIndex == TBaseKeyIterator<false>::Set.Num())
296 {
297 this->NextIndex = TBaseKeyIterator<false>::Index;
298 }
299
300 this->Index = INDEX_NONE;
301 }
302 };
303
304 /* Constructors */
305
307
308 [[nodiscard]] explicit consteval UE_TCOMPACT_SET(EConstEval)
310 {
311 }
312
317
322
327
328 [[nodiscard]] UE_TCOMPACT_SET(std::initializer_list<ElementType> InitList)
329 {
331 }
332
337
339 template<typename OtherAllocator>
344
346 template<typename OtherAllocator>
351
353 {
354 UE_STATIC_ASSERT_WARN(TIsTriviallyRelocatable_V<InElementType>, "TMapBase can only be used with trivially relocatable types");
355
356 Empty(0);
357 }
358
360 // Start - intrusive TOptional<UE_TCOMPACT_SET> state //
362 constexpr static bool bHasIntrusiveUnsetOptionalState = true;
364
369 // End - intrusive TOptional<UE_TCOMPACT_SET> state //
371
372 /* Assignment operators */
373
375 {
376 if (this != &Copy)
377 {
378 // This could either take the full memory size of the Copy and prevent a rehash or
379 // only allocate the required set but have to hash everything again (i.e. perf vs memory)
380 // Could try a middle ground of allowing extra memory if it's within slack margins.
381 // Going for memory savings for now
382
383 // Not using Empty(NumElements) to avoid clearing the hash memory since we'll rebuild it anyway
384 // We need to make sure the relevant parts are cleared so ResizeAllocation can run safely and with minimal cost
386 this->NumElements = 0;
387
388 ResizeAllocation(Copy.NumElements);
389
390 this->NumElements = Copy.NumElements;
391 ConstructItems<ElementType>(GetData(), Copy.GetData(), this->NumElements);
392
393 Rehash();
394 }
395 return *this;
396 }
397
399 {
400 if (this != &Other)
401 {
402 this->Elements.MoveToEmpty(Other.Elements);
403 this->NumElements = Other.NumElements;
404 this->MaxElements = Other.MaxElements;
405
406 Other.NumElements = 0;
407 Other.MaxElements = 0;
408 }
409
410 return *this;
411 }
412
414 template<typename OtherAllocator>
421
423 template<typename OtherAllocator>
430
431 UE_TCOMPACT_SET& operator=(std::initializer_list<ElementType> InitList)
432 {
433 Reset();
435 return *this;
436 }
437
444 template <
445 typename OtherKeyFuncs,
446 typename AliasElementType = ElementType
448 >
456
464 template <
465 typename OtherKeyFuncs,
466 typename OtherAllocator,
467 typename AliasElementType = ElementType
469 >
477
483 {
485 this->NumElements = 0;
486
487 ResizeAllocation(ExpectedNumElements);
488 if (this->MaxElements > 0)
489 {
490 GetHashTableView().Reset();
491 }
492 }
493
495 void Reset()
496 {
497 if (this->NumElements > 0)
498 {
500 this->NumElements = 0;
501
502 GetHashTableView().Reset();
503 }
504 }
505
507 void Shrink()
508 {
509 if (this->NumElements != this->MaxElements)
510 {
511 if (ResizeAllocationPreserveData(this->NumElements))
512 {
513 Rehash();
514 }
515 }
516 }
517
520 {
521 // makes sense only when Number > Elements.Num() since TSparseArray::Reserve
522 // does any work only if that's the case
523 if ((USizeType)Number > (USizeType)this->MaxElements)
524 {
525 // Trap negative reserves
526 if (Number < 0)
527 {
528 UE::Core::Private::OnInvalidSetNum((unsigned long long)Number);
529 }
530
531 if (ResizeAllocationPreserveData(Number))
532 {
533 Rehash();
534 }
535 }
536 }
537
539 void Compact()
540 {
541 }
542
545 {
546 ensureMsgf(false, TEXT("Compact sets are always compact so CompactStable will not do anything. If you hit this then you likely need to use a different pattern to maintain order, see RemoveStable"));
547 }
548
551 {
552 }
553
555 void Relax()
556 {
557 }
558
565 {
566 return Super::GetAllocatedSize(GetSetLayout());
567 }
568
570 inline void CountBytes(FArchive& Ar) const
571 {
572 const FCompactSetLayout Layout = GetSetLayout();
573 Ar.CountBytes(Super::GetTotalMemoryRequiredInBytes(this->NumElements, Layout), Super::GetTotalMemoryRequiredInBytes(this->MaxElements, Layout));
574 }
575
576 /* Calculate the size of the hash table from the number of elements in the set assuming the default number of hash elements */
577 [[nodiscard]] UE_FORCEINLINE_HINT static constexpr size_t GetTotalMemoryRequiredInBytes(uint32 NumElements)
578 {
579 return Super::GetTotalMemoryRequiredInBytes(NumElements, GetSetLayout());
580 }
581
588 {
589 return Id.AsInteger() >= 0 && Id.AsInteger() < this->NumElements;
590 }
591
597 {
598 checkSlow((this->NumElements >= 0) & (this->MaxElements >= this->NumElements)); // & for one branch
599 }
600
606 inline void RangeCheck(FSetElementId Id) const
607 {
609
610 // Template property, branch will be optimized out
611 if constexpr (AllocatorType::RequireRangeCheck)
612 {
613 checkf(IsValidId(Id), TEXT("Array index out of bounds: %d into an array of size %lld"), Id.AsInteger(), (long long)this->NumElements); // & for one branch
614 }
615 }
616
619 {
620 RangeCheck(Id);
621 return GetData()[Id.AsInteger()];
622 }
623
626 {
627 RangeCheck(Id);
628 return GetData()[Id.AsInteger()];
629 }
630
633 {
634 RangeCheck(Id);
635 return GetData()[Id.AsInteger()];
636 }
637
639 [[nodiscard]] inline const ElementType& Get(FSetElementId Id) const
640 {
641 RangeCheck(Id);
642 return GetData()[Id.AsInteger()];
643 }
644
653 {
654 return EmplaceByHash(KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(InElement)), InElement, bIsAlreadyInSetPtr);
655 }
657 {
658 return EmplaceByHash(KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(InElement)), MoveTempIfPossible(InElement), bIsAlreadyInSetPtr);
659 }
660
678
686 template<typename ArgType = ElementType>
688 {
690
692 {
693 *bIsAlreadyInSetPtr = Result.Value;
694 }
695
696 return Result.Key;
697 }
698
706 template <typename... ArgTypes>
708 {
709 alignas(alignof(ElementType))char StackElement[sizeof(ElementType)];
711 SizeType ExistingIndex(INDEX_NONE);
712
713 const KeyInitType Key = KeyFuncs::GetSetKey(TempElement);
714 const uint32 KeyHash = KeyFuncs::GetKeyHash(Key);
715
716 if constexpr (!KeyFuncs::bAllowDuplicateKeys)
717 {
718 ExistingIndex = FindIndexByHash(KeyHash, Key);
719 }
720
721 const bool bAlreadyInSet = ExistingIndex != INDEX_NONE;
722
723 if (!bAlreadyInSet)
724 {
726 ElementType& NewElement = AddUninitialized(KeyHash);
728 }
729 else
730 {
733 }
734
736 }
737
747 template<typename ArgType = ElementType>
749 {
751
753 {
754 *bIsAlreadyInSetPtr = Result.Value;
755 }
756
757 return Result.Key;
758 }
759
769 template <typename... ArgTypes>
771 {
772 alignas(alignof(ElementType))char StackElement[sizeof(ElementType)];
774 SizeType ExistingIndex(INDEX_NONE);
775
776 if constexpr (!KeyFuncs::bAllowDuplicateKeys)
777 {
778 ExistingIndex = FindIndexByHash(KeyHash, KeyFuncs::GetSetKey(TempElement));
779 }
780
781 const bool bAlreadyInSet = ExistingIndex != INDEX_NONE;
782
783 if (!bAlreadyInSet)
784 {
786 ElementType& NewElement = AddUninitialized(KeyHash);
788 }
789 else
790 {
793 }
794
796 }
797
806 {
807 return FindOrAddByHash(KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(InElement)), InElement, bIsAlreadyInSetPtr);
808 }
810 {
811 return FindOrAddByHash(KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(InElement)), MoveTempIfPossible(InElement), bIsAlreadyInSetPtr);
812 }
813
823 template<typename ElementReferenceType>
825 {
826 const SizeType ExistingIndex = FindIndexByHash(KeyHash, KeyFuncs::GetSetKey(InElement));
829 {
831 }
832 if (bIsAlreadyInSet)
833 {
834 return GetData()[ExistingIndex];
835 }
836
837 ElementType& NewElement = AddUninitialized(KeyHash);
839 }
840
842 {
843 Reserve(this->NumElements + InElements.Num());
844 for (const ElementType& Element : InElements)
845 {
846 Add(Element);
847 }
848 }
849
850 template<typename ArrayAllocator>
852 {
853 Reserve(this->NumElements + InElements.Num());
854 for (ElementType& Element : InElements)
855 {
856 Add(MoveTempIfPossible(Element));
857 }
858 InElements.Reset();
859 }
860
865 template<typename OtherAllocator>
867 {
868 Reserve(this->NumElements + OtherSet.Num());
869 for (const ElementType& Element : OtherSet)
870 {
871 Add(Element);
872 }
873 }
874
875 template<typename OtherAllocator>
877 {
878 Reserve(this->NumElements + OtherSet.Num());
879 for (ElementType& Element : OtherSet)
880 {
881 Add(MoveTempIfPossible(Element));
882 }
883 OtherSet.Reset();
884 }
885
886 void Append(std::initializer_list<ElementType> InitList)
887 {
888 Reserve(this->NumElements + (int32)InitList.size());
889 for (const ElementType& Element : InitList)
890 {
891 Add(Element);
892 }
893 }
894
900 template <
901 typename OtherKeyFuncs,
902 typename OtherAllocator,
903 typename AliasElementType = ElementType
905 >
915
921 template <
922 typename OtherKeyFuncs,
923 typename AliasElementType = ElementType
925 >
936
943 {
944 return (this->NumElements > 0) ? GetData() : nullptr;
945 }
947 {
948 return const_cast<UE_TCOMPACT_SET*>(this)->FindArbitraryElement();
949 }
950
951
957 [[nodiscard]] FSetElementId FindId(KeyInitType Key) const
958 {
959 return FSetElementId::FromInteger(FindIndexByHash(KeyFuncs::GetKeyHash(Key), Key));
960 }
961
967 template<typename ComparableKey>
969 {
970 checkSlow(KeyHash == KeyFuncs::GetKeyHash(Key));
971 return FSetElementId::FromInteger(FindIndexByHash(KeyHash, Key));
972 }
973
979 [[nodiscard]] inline ElementType* Find(KeyInitType Key)
980 {
981 SizeType ElementIndex = FindIndexByHash(KeyFuncs::GetKeyHash(Key), Key);
982 if (ElementIndex != INDEX_NONE)
983 {
984 return GetData() + ElementIndex;
985 }
986 else
987 {
988 return nullptr;
989 }
990 }
991
997 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* Find(KeyInitType Key) const
998 {
999 return const_cast<UE_TCOMPACT_SET*>(this)->Find(Key);
1000 }
1001
1007 template<typename ComparableKey>
1009 {
1010 SizeType ElementIndex = FindIndexByHash(KeyHash, Key);
1011 if (ElementIndex != INDEX_NONE)
1012 {
1013 return GetData() + ElementIndex;
1014 }
1015 else
1016 {
1017 return nullptr;
1018 }
1019 }
1020
1021 template<typename ComparableKey>
1022 [[nodiscard]] const ElementType* FindByHash(uint32 KeyHash, const ComparableKey& Key) const
1023 {
1024 return const_cast<UE_TCOMPACT_SET*>(this)->FindByHash(KeyHash, Key);
1025 }
1026
1031 void Remove(FSetElementId ElementId)
1032 {
1033 RemoveByIndex(ElementId.AsInteger());
1034 }
1035
1041 int32 Remove(KeyInitType Key)
1042 {
1043 if (this->NumElements)
1044 {
1045 return RemoveImpl(KeyFuncs::GetKeyHash(Key), Key);
1046 }
1047
1048 return 0;
1049 }
1050
1056 {
1057 RemoveByIndex<true>(ElementId.AsInteger());
1058 }
1059
1065 int32 RemoveStable(KeyInitType Key)
1066 {
1067 if (this->NumElements)
1068 {
1069 return RemoveImplStable(KeyFuncs::GetKeyHash(Key), Key);
1070 }
1071
1072 return 0;
1073 }
1074
1082 template<typename ComparableKey>
1084 {
1085 checkSlow(KeyHash == KeyFuncs::GetKeyHash(Key));
1086
1087 if (this->NumElements)
1088 {
1089 return RemoveImpl(KeyHash, Key);
1090 }
1091
1092 return 0;
1093 }
1094
1100 [[nodiscard]] UE_FORCEINLINE_HINT bool Contains(KeyInitType Key) const
1101 {
1102 return FindIndexByHash(KeyFuncs::GetKeyHash(Key), Key) != INDEX_NONE;
1103 }
1104
1110 template<typename ComparableKey>
1111 [[nodiscard]] inline bool ContainsByHash(uint32 KeyHash, const ComparableKey& Key) const
1112 {
1113 checkSlow(KeyHash == KeyFuncs::GetKeyHash(Key));
1114 return FindIndexByHash(KeyHash, Key) != INDEX_NONE;
1115 }
1116
1120 template<typename PredicateType>
1121 void Sort(const PredicateType& Predicate)
1122 {
1123 TArrayView<ElementType>(GetData(), this->NumElements).Sort(Predicate);
1124 Rehash();
1125 }
1126
1130 template<typename PredicateType>
1131 void StableSort(const PredicateType& Predicate)
1132 {
1133 TArrayView<ElementType>(GetData(), this->NumElements).StableSort(Predicate);
1134 Rehash();
1135 }
1136
1141 void Dump(FOutputDevice& Ar) const
1142 {
1143 if (this->MaxElements == 0)
1144 {
1145 Ar.Logf(TEXT("UE_TCOMPACT_SET: empty"), this->NumElements, this->MaxElements);
1146 }
1147 else if (this->MaxElements > 0)
1148 {
1149 FConstCompactHashTableView HashTable = this->GetConstHashTableView();
1150
1151 Ar.Logf(TEXT("UE_TCOMPACT_SET: %i elements, %i max elements, %i hash slots"), this->NumElements, this->MaxElements, HashTable.GetHashCount());
1152
1153 for (uint32 HashIndex = 0; HashIndex < HashTable.GetHashCount(); ++HashIndex)
1154 {
1155 // Count the numTableIndexber of elements in this hash bucket.
1157 for (uint32 ElementIndex = HashTable.GetFirstByIndex(HashIndex); ElementIndex != INDEX_NONE; ElementIndex = HashTable.GetNext(ElementIndex, this->NumElements))
1158 {
1160 }
1161
1162 Ar.Logf(TEXT(" Hash[%i] = %i"), HashIndex, NumElementsInBucket);
1163 }
1164 }
1165 else
1166 {
1167 // MaxElements == INDEX_NONE is a TOptional that's null, anything else is just garbage data
1168 checkNoEntry();
1169 }
1170 }
1171
1174 {
1175 const bool bOtherSmaller = (this->NumElements > OtherSet.NumElements);
1176 const UE_TCOMPACT_SET& A = (bOtherSmaller ? OtherSet : *this);
1177 const UE_TCOMPACT_SET& B = (bOtherSmaller ? *this : OtherSet);
1178
1179 UE_TCOMPACT_SET Result;
1180 Result.Reserve(A.NumElements); // Worst case is everything in smaller is in larger
1181
1182 for (const ElementType& Element : A)
1183 {
1184 if (B.Contains(KeyFuncs::GetSetKey(Element)))
1185 {
1186 Result.Add(Element);
1187 }
1188 }
1189 return Result;
1190 }
1191
1194 {
1195 UE_TCOMPACT_SET Result;
1196 Result.Reserve(this->NumElements + OtherSet.NumElements); // Worst case is 2 totally unique Sets
1197
1198 for (const ElementType& Element : *this)
1199 {
1200 Result.Add(Element);
1201 }
1202 for (const ElementType& Element : OtherSet)
1203 {
1204 Result.Add(Element);
1205 }
1206 return Result;
1207 }
1208
1211 {
1212 UE_TCOMPACT_SET Result;
1213 Result.Reserve(this->NumElements); // Worst case is no elements of this are in Other
1214
1215 for (const ElementType& Element : *this)
1216 {
1217 if (!OtherSet.Contains(KeyFuncs::GetSetKey(Element)))
1218 {
1219 Result.Add(Element);
1220 }
1221 }
1222 return Result;
1223 }
1224
1233 {
1234 bool bIncludesSet = true;
1235 if (OtherSet.NumElements <= this->NumElements)
1236 {
1237 for (const ElementType& Element : OtherSet)
1238 {
1239 if (!Contains(KeyFuncs::GetSetKey(Element)))
1240 {
1241 bIncludesSet = false;
1242 break;
1243 }
1244 }
1245 }
1246 else
1247 {
1248 // Not possible to include if it is bigger than us
1249 bIncludesSet = false;
1250 }
1251 return bIncludesSet;
1252 }
1253
1256 {
1257 return TArray<ElementType>(GetData(), this->NumElements);
1258 }
1259
1265
1268 {
1269 return TIterator(*this);
1270 }
1271
1277
1282 #if TARRAY_RANGED_FOR_CHECKS // Only use iterators with checks enabled to get modification check, otherwise it's just a waste of compile/runtime resources
1285
1286 [[nodiscard]] UE_FORCEINLINE_HINT TRangedForIterator begin() { return TRangedForIterator(this->NumElements, GetData()); }
1288 [[nodiscard]] UE_FORCEINLINE_HINT TRangedForIterator end() { return TRangedForIterator(this->NumElements, GetData() + this->NumElements); }
1289 [[nodiscard]] UE_FORCEINLINE_HINT TRangedForConstIterator end() const { return TRangedForConstIterator(this->NumElements, GetData() + this->NumElements); }
1290 #else
1293
1295 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* begin() const { return GetData(); }
1297 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* end() const { return GetData() + this->NumElements; }
1298 #endif
1299
1300 // Sets are deliberately prevented from being hashed or compared, because this would hide potentially major performance problems behind default operations.
1301 friend uint32 GetTypeHash(const UE_TCOMPACT_SET& Set) = delete;
1302 friend bool operator==(const UE_TCOMPACT_SET&, const UE_TCOMPACT_SET&) = delete;
1303 friend bool operator!=(const UE_TCOMPACT_SET&, const UE_TCOMPACT_SET&) = delete;
1304
1306 {
1307 checkf(!Writer.Is32BitTarget(), TEXT("UE_TCOMPACT_SET does not currently support freezing for 32bits"));
1309 {
1310 if (this->NumElements > 0)
1311 {
1312 const ElementType* Data = GetData();
1313 check(Data);
1315 ArrayWriter.WriteAlignment(GetAlignment());
1316
1317 // Write active element data
1318 ArrayWriter.WriteObjectArray(Data, StaticGetTypeLayoutDesc<ElementType>(), this->NumElements);
1319 ArrayWriter.WritePaddingToSize(this->MaxElements * sizeof(ElementType));
1320
1321 // Write remaining byte and hash table data
1322 const FCompactSetLayout Layout = GetSetLayout();
1323 const HashCountType* HashTable = this->GetHashTableMemory(Layout);
1324 const uint8* HashTableDataEnd = (const uint8*)Data + Super::GetTotalMemoryRequiredInBytes(this->MaxElements, *HashTable, Layout);
1325 ArrayWriter.WriteBytes(HashTable, HashTableDataEnd - (const uint8*)HashTable);
1326
1327 Writer.WriteBytes(this->NumElements);
1328 Writer.WriteBytes(this->MaxElements);
1329 }
1330 else
1331 {
1332 Writer.WriteBytes(UE_TCOMPACT_SET());
1333 }
1334 }
1335 else
1336 {
1337 Writer.WriteBytes(UE_TCOMPACT_SET());
1338 }
1339 }
1340
1341 void CopyUnfrozen(const FMemoryUnfreezeContent& Context, void* Dst) const
1342 {
1343 ::new(Dst) UE_TCOMPACT_SET();
1344
1346 {
1348
1349 UE_TCOMPACT_SET* DstObject = static_cast<UE_TCOMPACT_SET*>(Dst);
1350
1351 {
1352 DstObject->ResizeAllocation(this->MaxElements);
1353 DstObject->NumElements = this->NumElements;
1354
1355 const ElementType* SrcData = GetData();
1356 ElementType* DstData = DstObject->GetData();
1357
1358 for (int32 Index = 0; Index < this->NumElements; ++Index)
1359 {
1360 Context.UnfreezeObject(SrcData + Index, ElementTypeDesc, DstData + Index);
1361 }
1362
1363 const FCompactSetLayout Layout = GetSetLayout();
1364 const HashCountType* SrcHashTable = this->GetHashTableMemory(Layout);
1365 const uint8* SrcHashTableEnd = (const uint8 *)SrcData + Super::GetTotalMemoryRequiredInBytes(this->MaxElements, *SrcHashTable, Layout);
1366
1367 HashCountType* DstHashTable = (HashCountType*)DstObject->GetHashTableMemory(Layout);
1369 }
1370 }
1371 }
1372
1373 static void AppendHash(const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher)
1374 {
1376 {
1378 }
1379 }
1380
1381private:
1382 /* Get the alignment required for the allocation */
1383 [[nodiscard]] UE_FORCEINLINE_HINT static constexpr size_t GetAlignment()
1384 {
1385 return FGenericPlatformMath::Max<size_t>(alignof(ElementType), UE::Core::CompactHashTable::GetMemoryAlignment());
1386 }
1387
1389 {
1390 return (ElementType*)this->Elements.GetAllocation();
1391 }
1392
1394 {
1395 return (const ElementType*)this->Elements.GetAllocation();
1396 }
1397
1398 [[nodiscard]] UE_FORCEINLINE_HINT static constexpr FCompactSetLayout GetSetLayout()
1399 {
1400 return { sizeof(ElementType), GetAlignment() };
1401 }
1402
1404 {
1405 return Super::GetHashTableView(GetSetLayout());
1406 }
1407
1408 [[nodiscard]] UE_FORCEINLINE_HINT FConstCompactHashTableView GetConstHashTableView() const
1409 {
1410 return Super::GetConstHashTableView(GetSetLayout());
1411 }
1412
1413 // Use if you're going to reset/rehash regardless of the results
1414 UE_FORCEINLINE_HINT void ResizeAllocation(SizeType NewMaxElements)
1415 {
1416 (void)Super::ResizeAllocationPreserveData(NewMaxElements, GetSetLayout(), false);
1417 }
1418
1419 // Use this if you'll be keeping the element data
1420 [[nodiscard]] bool ResizeAllocationPreserveData(SizeType NewMaxElements, bool bPreserveHashData = true)
1421 {
1422 return Super::ResizeAllocationPreserveData(NewMaxElements, GetSetLayout(), bPreserveHashData);
1423 }
1424
1426 void Rehash()
1427 {
1428 if (this->MaxElements > 0)
1429 {
1430 const ElementType* ElementData = GetData();
1431 FCompactHashTableView HashTable = GetHashTableView();
1432
1433 HashTable.Reset();
1434
1435 for (int32 Index = 0; Index < this->NumElements; ++Index)
1436 {
1437 HashTable.Add(Index, KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(ElementData[Index])));
1438 }
1439 }
1440 }
1441
1442 [[nodiscard]] ElementType& AddUninitialized(uint32 KeyHash)
1443 {
1444 checkSlow(this->MaxElements >= 0);
1445 if (this->NumElements == this->MaxElements)
1446 {
1447 Reserve(this->AllocatorCalculateSlackGrow(this->NumElements + 1, GetSetLayout()));
1448 }
1449 GetHashTableView().Add(this->NumElements, KeyHash);
1450 return GetData()[this->NumElements++];
1451 }
1452
1458 template<typename ComparableKey>
1459 [[nodiscard]] SizeType FindIndexByHash(uint32 KeyHash, const ComparableKey& Key) const
1460 {
1461 if (this->NumElements == 0)
1462 {
1463 return INDEX_NONE;
1464 }
1465
1466 const ElementType* ElementData = GetData();
1467 const HashCountType* HashTable = this->GetHashTableMemory(GetSetLayout());
1468 const uint8* NextIndicesData = (const uint8*)(HashTable + 1);
1469 const uint32 HashCount = *HashTable;
1470
1471 // Inlining this can save up to 40% perf compared to GetHashTableView().Find()
1472 #define UE_COMPACTHASHTABLE_EXECUTEBYTYPE(Type) \
1473 const Type* NextIndices = (const Type *)NextIndicesData; \
1474 const Type* HashIndices = NextIndices + this->MaxElements; \
1475 for (Type Index = HashIndices[KeyHash & (HashCount-1)]; Index != (Type)INDEX_NONE; Index = NextIndices[Index]) \
1476 { \
1477 checkSlow((SizeType)Index < this->NumElements); \
1478 if (KeyFuncs::Matches(KeyFuncs::GetSetKey(ElementData[Index]), Key)) \
1479 { \
1480 return Index; \
1481 } \
1482 }
1483
1484 UE_COMPACTHASHTABLE_CALLBYTYPE(this->MaxElements)
1485 #undef UE_COMPACTHASHTABLE_EXECUTEBYTYPE
1486
1487 return INDEX_NONE;
1488 }
1489
1490 template <bool IsStable = false>
1491 void RemoveByIndex(const SizeType ElementIndex)
1492 {
1493 checkf(ElementIndex >= 0 && ElementIndex < this->NumElements, TEXT("Invalid ElementIndex passed to UE_TCOMPACT_SET::RemoveByIndex"));
1494 RemoveByIndexAndHash<IsStable>(ElementIndex, KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(GetData()[ElementIndex])));
1495 }
1496
1497 template <bool IsStable = false>
1498 void RemoveByIndexAndHash(const SizeType ElementIndex, const uint32 KeyHash)
1499 {
1500 checkf(ElementIndex >= 0 && ElementIndex < this->NumElements, TEXT("Invalid ElementIndex passed to UE_TCOMPACT_SET::RemoveByIndex"));
1501
1503 FCompactHashTableView HashTable = GetHashTableView();
1504
1505 const SizeType LastElementIndex = this->NumElements - 1;
1506 if (ElementIndex == LastElementIndex)
1507 {
1508 HashTable.Remove(ElementIndex, KeyHash, ElementIndex, KeyHash);
1509 ElementsData[LastElementIndex].~ElementType();
1510 }
1511 else
1512 {
1513 if constexpr (IsStable)
1514 {
1515 HashTable.RemoveStable(ElementIndex, KeyHash);
1516
1517 ElementsData[ElementIndex].~ElementType();
1518 RelocateConstructItems<ElementType>(ElementsData + ElementIndex, ElementsData + ElementIndex + 1, LastElementIndex - ElementIndex);
1519 }
1520 else
1521 {
1522 const uint32 LastElementHash = KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(ElementsData[LastElementIndex]));
1523 HashTable.Remove(ElementIndex, KeyHash, LastElementIndex, LastElementHash);
1524
1525 MoveByRelocate(ElementsData[ElementIndex], ElementsData[LastElementIndex]);
1526 }
1527 }
1528
1529 --this->NumElements;
1530 }
1531
1532 template<typename ComparableKey, bool IsStable = false>
1533 int32 RemoveImpl(uint32 KeyHash, const ComparableKey& Key)
1534 {
1535 checkSlow(this->NumElements > 0);
1537
1538 const ElementType* ElementsData = GetData();
1539 FCompactHashTableView HashTable = GetHashTableView();
1540
1541 SizeType LastElementIndex = INDEX_NONE;
1542 SizeType ElementIndex = HashTable.GetFirst(KeyHash);
1543
1544 while (ElementIndex != INDEX_NONE)
1545 {
1546 if (KeyFuncs::Matches(KeyFuncs::GetSetKey(ElementsData[ElementIndex]), Key))
1547 {
1548 RemoveByIndexAndHash<IsStable>(ElementIndex, KeyHash);
1550
1551 if constexpr (!KeyFuncs::bAllowDuplicateKeys)
1552 {
1553 // If the hash disallows duplicate keys, we're done removing after the first matched key.
1554 break;
1555 }
1556 else
1557 {
1558 if (LastElementIndex == INDEX_NONE)
1559 {
1560 ElementIndex = HashTable.GetFirst(KeyHash);
1561 }
1562 else
1563 {
1564 if (LastElementIndex == this->NumElements) // Would have been remapped to ElementIndex
1565 {
1566 LastElementIndex = ElementIndex;
1567 }
1568
1569 ElementIndex = HashTable.GetNext(LastElementIndex, this->NumElements);
1570 }
1571 }
1572 }
1573 else
1574 {
1575 LastElementIndex = ElementIndex;
1576 ElementIndex = HashTable.GetNext(LastElementIndex, this->NumElements);
1577 }
1578 }
1579
1580 return NumRemovedElements;
1581 }
1582
1583 template<typename ComparableKey>
1584 UE_FORCEINLINE_HINT int32 RemoveImplStable(uint32 KeyHash, const ComparableKey& Key)
1585 {
1586 return RemoveImpl<ComparableKey, true>(KeyHash, Key);
1587 }
1588};
1589
1590template<typename RangeType>
1592
1593namespace Freeze
1594{
1595 template<typename ElementType, typename KeyFuncs, typename Allocator>
1600
1601 template<typename ElementType, typename KeyFuncs, typename Allocator>
1607
1608 template<typename ElementType, typename KeyFuncs, typename Allocator>
1610 {
1612 return DefaultAppendHash(TypeDesc, LayoutParams, Hasher);
1613 }
1614}
1615
1617
1619{
1621 template<typename ElementType, typename KeyFuncs, typename Allocator>
1623 {
1624 Set.CountBytes(Ar);
1625
1626 int32 NumElements = Set.Num();
1627 Ar << NumElements;
1628
1629 if (Ar.IsLoading())
1630 {
1631 // We can skip the reset on Empty and do it once at the end with Rehash
1632 DestructItems(Set.GetData(), Set.Num());
1633 Set.NumElements = 0;
1634 Set.ResizeAllocation(NumElements);
1635
1636 ElementType* Data = Set.GetData();
1637 for (int32 ElementIndex = 0; ElementIndex < NumElements; ElementIndex++)
1638 {
1639 Ar << *::new((void*)(Data + ElementIndex)) ElementType;
1640 }
1641
1642 Set.NumElements = NumElements;
1643 Set.Rehash();
1644 }
1645 else
1646 {
1647 for (ElementType& Element : Set)
1648 {
1649 Ar << Element;
1650 }
1651 }
1652 return Ar;
1653 }
1654
1656 template<typename ElementType, typename KeyFuncs, typename Allocator>
1658 {
1659 int32 NumElements = Set.Num();
1660 FStructuredArchive::FArray Array = Slot.EnterArray(NumElements);
1661
1662 if (Slot.GetUnderlyingArchive().IsLoading())
1663 {
1664 // We can skip the reset on Empty and do it once at the end with Rehash
1665 DestructItems(Set.GetData(), Set.Num());
1666 Set.NumElements = 0;
1667 Set.ResizeAllocation(NumElements);
1668
1669 ElementType* Data = Set.GetData();
1670 for (int32 ElementIndex = 0; ElementIndex < NumElements; ElementIndex++)
1671 {
1673 ElementSlot << *::new((void*)(Data + ElementIndex)) ElementType;
1674 }
1675
1676 Set.NumElements = NumElements;
1677 Set.Rehash();
1678 }
1679 else
1680 {
1681 for (ElementType& Element : Set)
1682 {
1684 ElementSlot << Element;
1685 }
1686 }
1687 }
1688
1689 // Legacy comparison operators. Note that these also test whether the set's elements were added in the same order!
1690 template<typename ElementType, typename KeyFuncs, typename Allocator>
1692 {
1693 return A.Num() == B.Num() && CompareItems(A.GetData(), B.GetData(), A.Num());
1694 }
1695};
1696
1698template<typename ElementType, typename KeyFuncs, typename Allocator>
1700{
1701 return TSETPRIVATEFRIEND::Serialize(Ar, Set);
1702}
1703
1705template<typename ElementType, typename KeyFuncs, typename Allocator>
1707{
1708 TSETPRIVATEFRIEND::SerializeStructured(Ar, Set);
1709}
1710
1711// Legacy comparison operators. Note that these also test whether the set's elements were added in the same order!
1712template<typename ElementType, typename KeyFuncs, typename Allocator>
1714{
1715 return TSETPRIVATEFRIEND::LegacyCompareEqual(A, B);
1716}
1717template<typename ElementType, typename KeyFuncs, typename Allocator>
1719{
1720 return !TSETPRIVATEFRIEND::LegacyCompareEqual(A, B);
1721}
1722
1723template <typename ElementType, typename KeyFuncs, typename Allocator> struct TIsTSet< UE_TCOMPACT_SET<ElementType, KeyFuncs, Allocator>> { enum { Value = true }; };
1724template <typename ElementType, typename KeyFuncs, typename Allocator> struct TIsTSet<const UE_TCOMPACT_SET<ElementType, KeyFuncs, Allocator>> { enum { Value = true }; };
1725template <typename ElementType, typename KeyFuncs, typename Allocator> struct TIsTSet< volatile UE_TCOMPACT_SET<ElementType, KeyFuncs, Allocator>> { enum { Value = true }; };
1726template <typename ElementType, typename KeyFuncs, typename Allocator> struct TIsTSet<const volatile UE_TCOMPACT_SET<ElementType, KeyFuncs, Allocator>> { enum { Value = true }; };
1727
1728#undef TSETPRIVATEFRIEND
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define checkNoEntry()
Definition AssertionMacros.h:316
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
UE_FORCEINLINE_HINT FLinearColor operator*(float Scalar, const FLinearColor &Color)
Definition Color.h:473
#define UE_COMPACTHASHTABLE_CALLBYTYPE(NextIndexCount)
Definition CompactHashTable.h:24
FArchive & operator<<(FArchive &Ar, UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &Set)
Definition CompactSet.h.inl:1699
bool LegacyCompareEqual(const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &A, const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &B)
Definition CompactSet.h.inl:1713
bool LegacyCompareNotEqual(const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &A, const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &B)
Definition CompactSet.h.inl:1718
#define UE_TCOMPACT_SET
Definition CompactSet.h:5
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_STATIC_ASSERT_WARN(bExpression, Message)
Definition CoreMiscDefines.h:431
EInPlace
Definition CoreMiscDefines.h:162
@ InPlace
Definition CoreMiscDefines.h:162
EConstEval
Definition CoreMiscDefines.h:161
@ ConstEval
Definition CoreMiscDefines.h:161
#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::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FORCEINLINE constexpr void DestructItems(ElementType *Element, SizeType Count)
Definition MemoryOps.h:81
FORCEINLINE bool CompareItems(const ElementType *A, const ElementType *B, SizeType Count)
Definition MemoryOps.h:287
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
typename TElementType< T >::Type TElementType_T
Definition ElementType.h:57
UE_FORCEINLINE_HINT bool operator!=(const FIndexedPointer &Other) const
Definition LockFreeList.h:76
#define DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T)
Definition MemoryLayout.h:661
@ Num
Definition MetalRHIPrivate.h:234
const bool
Definition NetworkReplayStreaming.h:178
TIndexedContainerIterator< const TArray< FPreviewAttachedObjectPair >, const FPreviewAttachedObjectPair, int32 > TConstIterator
Definition PreviewAssetAttachComponent.h:69
TIndexedContainerIterator< TArray< FPreviewAttachedObjectPair >, FPreviewAttachedObjectPair, int32 > TIterator
Definition PreviewAssetAttachComponent.h:68
#define UE_REQUIRES(...)
Definition Requires.h:86
void MoveByRelocate(T &A, T &B)
Definition SetUtilities.h:82
auto GetData(const TStringConversion< Converter, DefaultConversionSize > &Conversion) -> decltype(Conversion.Get())
Definition StringConv.h:802
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTempIfPossible(T &&Obj) noexcept
Definition UnrealTemplate.h:538
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
if(Failed) console_printf("Failed.\n")
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
virtual void CountBytes(SIZE_T InNum, SIZE_T InMax)
Definition Archive.h:125
Definition CompactHashTable.h:350
UE_FORCEINLINE_HINT void RemoveStable(uint32 Index, uint32 Key) const
Definition CompactHashTable.h:380
void Reset() const
Definition CompactHashTable.h:357
void Add(uint32 Index, uint32 Key) const
Definition CompactHashTable.h:365
UE_FORCEINLINE_HINT void Remove(uint32 Index, uint32 Key, uint32 LastIndex, uint32 OptLastKey) const
Definition CompactHashTable.h:373
Definition CompactHashTable.h:283
uint32 GetFirst(uint32 Key) const
Definition CompactHashTable.h:304
uint32 GetHashCount() const
Definition CompactHashTable.h:298
uint32 GetNext(uint32 Index, uint32 CurrentCount) const
Definition CompactHashTable.h:321
uint32 GetFirstByIndex(uint32 HashIndex) const
Definition CompactHashTable.h:313
Definition MemoryImageWriter.h:14
CORE_API uint32 WriteBytes(const void *Data, uint32 Size)
Definition MemoryImage.cpp:2143
CORE_API uint32 WriteAlignment(uint32 Alignment)
Definition MemoryImage.cpp:2133
bool Is32BitTarget() const
Definition MemoryImageWriter.h:26
CORE_API FMemoryImageWriter WritePointer(const FTypeLayoutDesc &StaticTypeDesc, const FTypeLayoutDesc &DerivedTypeDesc, uint32 *OutOffsetToBase=nullptr)
Definition MemoryImage.cpp:2153
Definition MemoryImageWriter.h:78
Definition OutputDevice.h:133
void Logf(const FmtType &Fmt)
Definition OutputDevice.h:234
Definition SecureHash.h:314
Definition SetUtilities.h:95
static UE_FORCEINLINE_HINT FSetElementId FromInteger(int32 Integer)
Definition SetUtilities.h:121
constexpr UE_FORCEINLINE_HINT int32 AsInteger() const
Definition SetUtilities.h:116
Definition StructuredArchiveSlots.h:172
Definition StructuredArchiveSlots.h:52
UE_API FStructuredArchiveArray EnterArray(int32 &Num)
Definition StructuredArchiveSlots.h:257
Definition ArrayView.h:139
Definition Array.h:670
Definition CompactSetBase.h:19
typename AllocatorType::SizeType SizeType
Definition CompactSetBase.h:22
Allocator AllocatorType
Definition CompactSetBase.h:21
ElementAllocatorType Elements
Definition CompactSetBase.h:276
UE_FORCEINLINE_HINT const HashCountType * GetHashTableMemory(const FCompactSetLayout Layout) const
Definition CompactSetBase.h:97
int32 AllocatorCalculateSlackGrow(int32 NewMaxElements, const FCompactSetLayout &Layout) const
Definition CompactSetBase.h:152
uint32 HashCountType
Definition CompactSetBase.h:74
Definition ScriptCompactSet.h:17
CORE_API FArchive & GetUnderlyingArchive() const
Definition StructuredArchiveSlots.cpp:7
CORE_API void Reserve(int32 CharacterCount)
Definition String.cpp.inl:307
Definition CompactSet.h.inl:255
void RemoveCurrent()
Definition CompactSet.h.inl:263
Definition CompactSet.h.inl:278
void RemoveCurrent()
Definition CompactSet.h.inl:287
typename Super::KeyArgumentType KeyArgumentType
Definition CompactSet.h.inl:283
Definition CompactSet.h.inl:58
ElementType & Get(FSetElementId Id)
Definition CompactSet.h.inl:632
void Dump(FOutputDevice &Ar) const
Definition CompactSet.h.inl:1141
ElementType * Find(KeyInitType Key)
Definition CompactSet.h.inl:979
TPair< FSetElementId, bool > EmplaceByHash(EInPlace, uint32 KeyHash, ArgTypes &&... InArgs)
Definition CompactSet.h.inl:770
friend bool operator==(const UE_TCOMPACT_SET &, const UE_TCOMPACT_SET &)=delete
UE_FORCEINLINE_HINT TConstIterator CreateConstIterator() const
Definition CompactSet.h.inl:1273
UE_TCOMPACT_SET & operator=(const UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &Other)
Definition CompactSet.h.inl:424
void Append(std::initializer_list< ElementType > InitList)
Definition CompactSet.h.inl:886
const ElementType * FindArbitraryElement() const
Definition CompactSet.h.inl:946
UE_TCOMPACT_SET Difference(const UE_TCOMPACT_SET &OtherSet) const
Definition CompactSet.h.inl:1210
UE_FORCEINLINE_HINT FSetElementId AddByHash(uint32 KeyHash, const ElementType &InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:670
UE_TCOMPACT_SET & operator=(UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &&Other)
Definition CompactSet.h.inl:415
void CopyUnfrozen(const FMemoryUnfreezeContent &Context, void *Dst) const
Definition CompactSet.h.inl:1341
int32 RemoveByHash(uint32 KeyHash, const ComparableKey &Key)
Definition CompactSet.h.inl:1083
void Reset()
Definition CompactSet.h.inl:495
UE_TCOMPACT_SET(const UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &Other)
Definition CompactSet.h.inl:347
void Append(const UE_TCOMPACT_SET< typename TContainerElementTypeCompatibility< ElementType >::CopyFromOtherType, OtherKeyFuncs, OtherAllocator > &OtherSet)
Definition CompactSet.h.inl:906
consteval UE_TCOMPACT_SET(EConstEval)
Definition CompactSet.h.inl:308
UE_FORCEINLINE_HINT FSetElementId Emplace(ArgType &&Arg, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:687
UE_FORCEINLINE_HINT UE_TCOMPACT_SET(const UE_TCOMPACT_SET &Copy)
Definition CompactSet.h.inl:313
UE_FORCEINLINE_HINT void CheckInvariants() const
Definition CompactSet.h.inl:596
KeyFuncs KeyFuncsType
Definition CompactSet.h.inl:61
void CountBytes(FArchive &Ar) const
Definition CompactSet.h.inl:570
bool Includes(const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &OtherSet) const
Definition CompactSet.h.inl:1232
void Sort(const PredicateType &Predicate)
Definition CompactSet.h.inl:1121
void SortFreeList()
Definition CompactSet.h.inl:550
ElementType * FindArbitraryElement()
Definition CompactSet.h.inl:942
UE_FORCEINLINE_HINT UE_TCOMPACT_SET(TArray< ElementType > &&InArray)
Definition CompactSet.h.inl:323
UE_FORCEINLINE_HINT UE_TCOMPACT_SET(TArrayView< const ElementType > InArrayView)
Definition CompactSet.h.inl:318
bool ContainsByHash(uint32 KeyHash, const ComparableKey &Key) const
Definition CompactSet.h.inl:1111
friend uint32 GetTypeHash(const UE_TCOMPACT_SET &Set)=delete
UE_TCOMPACT_SET(FIntrusiveUnsetOptionalState Tag)
Definition CompactSet.h.inl:365
UE_FORCEINLINE_HINT const ElementType * Find(KeyInitType Key) const
Definition CompactSet.h.inl:997
static void AppendHash(const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition CompactSet.h.inl:1373
UE_TCOMPACT_SET & operator=(UE_TCOMPACT_SET< typename TContainerElementTypeCompatibility< ElementType >::CopyFromOtherType, OtherKeyFuncs, Allocator > &&Other)
Definition CompactSet.h.inl:449
void Append(UE_TCOMPACT_SET< typename TContainerElementTypeCompatibility< ElementType >::CopyFromOtherType, OtherKeyFuncs, Allocator > &&OtherSet)
Definition CompactSet.h.inl:926
void WriteMemoryImage(FMemoryImageWriter &Writer) const
Definition CompactSet.h.inl:1305
UE_FORCEINLINE_HINT FSetElementId Add(const ElementType &InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:652
UE_FORCEINLINE_HINT ElementType & FindOrAdd(const InElementType &InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:805
void Append(UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &&OtherSet)
Definition CompactSet.h.inl:876
void Append(TArrayView< const ElementType > InElements)
Definition CompactSet.h.inl:841
TArrayView< const ElementType > ArrayView() const
Definition CompactSet.h.inl:1261
UE_TCOMPACT_SET & operator=(std::initializer_list< ElementType > InitList)
Definition CompactSet.h.inl:431
int32 RemoveStable(KeyInitType Key)
Definition CompactSet.h.inl:1065
UE_FORCEINLINE_HINT ElementType & FindOrAdd(InElementType &&InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:809
void Compact()
Definition CompactSet.h.inl:539
static constexpr bool bHasIntrusiveUnsetOptionalState
Definition CompactSet.h.inl:362
UE_FORCEINLINE_HINT TIterator CreateIterator()
Definition CompactSet.h.inl:1267
UE_FORCEINLINE_HINT const ElementType * end() const
Definition CompactSet.h.inl:1297
UE_TCOMPACT_SET Intersect(const UE_TCOMPACT_SET &OtherSet) const
Definition CompactSet.h.inl:1173
UE_FORCEINLINE_HINT bool Contains(KeyInitType Key) const
Definition CompactSet.h.inl:1100
UE_FORCEINLINE_HINT ~UE_TCOMPACT_SET()
Definition CompactSet.h.inl:352
void Relax()
Definition CompactSet.h.inl:555
static UE_FORCEINLINE_HINT constexpr size_t GetTotalMemoryRequiredInBytes(uint32 NumElements)
Definition CompactSet.h.inl:577
FSetElementId FindIdByHash(uint32 KeyHash, const ComparableKey &Key) const
Definition CompactSet.h.inl:968
UE_FORCEINLINE_HINT FSetElementId AddByHash(uint32 KeyHash, ElementType &&InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:674
UE_TCOMPACT_SET(UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &&Other)
Definition CompactSet.h.inl:340
void RangeCheck(FSetElementId Id) const
Definition CompactSet.h.inl:606
FSetElementId FindId(KeyInitType Key) const
Definition CompactSet.h.inl:957
UE_FORCEINLINE_HINT ElementType * begin()
Definition CompactSet.h.inl:1294
const ElementType * TRangedForConstIterator
Definition CompactSet.h.inl:1292
void Append(TArray< ElementType, ArrayAllocator > &&InElements)
Definition CompactSet.h.inl:851
UE_FORCEINLINE_HINT ElementType * end()
Definition CompactSet.h.inl:1296
TBaseKeyIterator< true > TConstKeyIterator
Definition CompactSet.h.inl:274
void Empty(int32 ExpectedNumElements=0)
Definition CompactSet.h.inl:482
ElementType * FindByHash(uint32 KeyHash, const ComparableKey &Key)
Definition CompactSet.h.inl:1008
UE_FORCEINLINE_HINT constexpr UE_TCOMPACT_SET()=default
UE_TCOMPACT_SET Union(const UE_TCOMPACT_SET &OtherSet) const
Definition CompactSet.h.inl:1193
UE_TCOMPACT_SET & operator=(const UE_TCOMPACT_SET &Copy)
Definition CompactSet.h.inl:374
UE_TCOMPACT_SET & operator=(UE_TCOMPACT_SET &&Other)
Definition CompactSet.h.inl:398
ElementType * TRangedForIterator
Definition CompactSet.h.inl:1291
UE_TCOMPACT_SET & operator=(const UE_TCOMPACT_SET< typename TContainerElementTypeCompatibility< ElementType >::CopyFromOtherType, OtherKeyFuncs, OtherAllocator > &Other)
Definition CompactSet.h.inl:470
UE_FORCEINLINE_HINT bool IsValidId(FSetElementId Id) const
Definition CompactSet.h.inl:587
UE_FORCEINLINE_HINT const ElementType * begin() const
Definition CompactSet.h.inl:1295
UE_FORCEINLINE_HINT FSetElementId Add(ElementType &&InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:656
const ElementType & Get(FSetElementId Id) const
Definition CompactSet.h.inl:639
void Append(const UE_TCOMPACT_SET< ElementType, KeyFuncs, OtherAllocator > &OtherSet)
Definition CompactSet.h.inl:866
const ElementType & operator[](FSetElementId Id) const
Definition CompactSet.h.inl:625
void Reserve(int32 Number)
Definition CompactSet.h.inl:519
UE_TCOMPACT_SET(std::initializer_list< ElementType > InitList)
Definition CompactSet.h.inl:328
InElementType ElementType
Definition CompactSet.h.inl:60
void Shrink()
Definition CompactSet.h.inl:507
void RemoveStable(FSetElementId ElementId)
Definition CompactSet.h.inl:1055
void StableSort(const PredicateType &Predicate)
Definition CompactSet.h.inl:1131
void CompactStable()
Definition CompactSet.h.inl:544
const ElementType * FindByHash(uint32 KeyHash, const ComparableKey &Key) const
Definition CompactSet.h.inl:1022
UE_TCOMPACT_SET(UE_TCOMPACT_SET &&Other)
Definition CompactSet.h.inl:333
TArray< ElementType > Array() const
Definition CompactSet.h.inl:1255
TBaseIterator< true > TConstIterator
Definition CompactSet.h.inl:251
friend bool operator!=(const UE_TCOMPACT_SET &, const UE_TCOMPACT_SET &)=delete
UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize() const
Definition CompactSet.h.inl:564
void Remove(FSetElementId ElementId)
Definition CompactSet.h.inl:1031
TPair< FSetElementId, bool > Emplace(EInPlace, ArgTypes &&... InArgs)
Definition CompactSet.h.inl:707
ElementType & operator[](FSetElementId Id)
Definition CompactSet.h.inl:618
int32 Remove(KeyInitType Key)
Definition CompactSet.h.inl:1041
UE_FORCEINLINE_HINT FSetElementId EmplaceByHash(uint32 KeyHash, ArgType &&Arg, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:748
ElementType & FindOrAddByHash(uint32 KeyHash, ElementReferenceType &&InElement, bool *bIsAlreadyInSetPtr=nullptr)
Definition CompactSet.h.inl:824
void SetNum(TArrayView< T > &View, int32 Num)
Definition AssetDataTagMap.cpp:1011
Definition Array.h:3955
UE_NODEBUG void IntrinsicWriteMemoryImage(FMemoryImageWriter &Writer, const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &)
Definition Array.h:3957
CORE_API uint32 DefaultAppendHash(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:575
CORE_API uint32 AppendHash(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:864
UE_NODEBUG uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent &Context, const TArray< T, AllocatorType > &Object, void *OutDst)
Definition Array.h:3963
UE_NODEBUG uint32 IntrinsicAppendHash(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition Array.h:3970
FNameFuncs< typename TGetKeyType< MapType >::Type > KeyFuncs
Definition PerPlatformProperties.h:107
bool operator==(const FCachedAssetKey &A, const FCachedAssetKey &B)
Definition AssetDataMap.h:501
uint32 GetFirst(uint32 Key, const IndexType *HashData, const uint32 HashCount)
Definition CompactHashTable.h:92
UE_FORCEINLINE_HINT constexpr size_t GetMemoryAlignment()
Definition CompactHashTable.h:69
implementation
Definition PlayInEditorLoadingScope.h:8
CORE_API void OnInvalidSetNum(unsigned long long NewNum)
Definition ContainerHelpers.cpp:12
FORCEINLINE UE_STRING_CLASS RhsType && Rhs
Definition String.cpp.inl:718
U16 Index
Definition radfft.cpp:71
Definition CompactSetBase.h:11
Definition IntrusiveUnsetOptionalState.h:71
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition MemoryLayout.h:799
Definition MemoryLayout.h:108
Definition ContainerAllocationPolicies.h:256
Definition Array.h:206
InElementType CopyFromOtherType
Definition ContainerElementTypeCompatibility.h:17
static constexpr void CopyingFromOtherType()
Definition ContainerElementTypeCompatibility.h:29
Definition MemoryLayout.h:626
Definition SetUtilities.h:14
@ Value
Definition SetUtilities.h:14
Definition RetainedRef.h:62
Definition CompactSet.h.inl:1619
static void SerializeStructured(FStructuredArchive::FSlot Slot, UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &Set)
Definition CompactSet.h.inl:1657
static bool LegacyCompareEqual(const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &A, const UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &B)
Definition CompactSet.h.inl:1691
static FArchive & Serialize(FArchive &Ar, UE_TCOMPACT_SET< ElementType, KeyFuncs, Allocator > &Set)
Definition CompactSet.h.inl:1622
Definition Tuple.h:652
TCallTraits< T >::ConstPointerType ConstPointerType
Definition UnrealTypeTraits.h:337