UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SmallListSet.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// Port of geometry3cpp small_list_set
4
5#pragma once
6
8#include "HAL/PlatformMath.h"
10#include "Templates/Function.h"
12#include "Util/DynamicVector.h"
13
14class FArchive;
15
16namespace UE
17{
18namespace Geometry
19{
20
36{
37protected:
39 static constexpr int32 NullValue = -1;
40
42 static constexpr int32 BLOCKSIZE = 8;
44 static constexpr int32 BLOCK_LIST_OFFSET = BLOCKSIZE + 1;
45
48
54
57
60
66
69
70
71public:
75 size_t Size() const
76 {
77 return ListHeads.GetLength();
78 }
79
83 GEOMETRYCORE_API void Resize(int32 NewSize);
84
85
90
103
108
109
113 bool IsAllocated(int32 ListIndex) const
114 {
115 return (ListIndex >= 0 && ListIndex < (int32)ListHeads.GetLength() && ListHeads[ListIndex] != NullValue);
116 }
117
121 GEOMETRYCORE_API void AllocateAt(int32 ListIndex);
122
123
127 GEOMETRYCORE_API void Insert(int32 ListIndex, int32 Value);
128
129
130
135 GEOMETRYCORE_API bool Remove(int32 ListIndex, int32 Value);
136
137
138
142 GEOMETRYCORE_API void Move(int32 FromIndex, int32 ToIndex);
143
144
145
149 GEOMETRYCORE_API void Clear(int32 ListIndex);
150
151
155 inline int32 GetCount(int32 ListIndex) const
156 {
157 checkSlow(ListIndex >= 0);
158 int32 block_ptr = ListHeads[ListIndex];
159 return (block_ptr == NullValue) ? 0 : ListBlocks[block_ptr];
160 }
161
162
167 inline int32 First(int32 ListIndex) const
168 {
169 checkSlow(ListIndex >= 0);
170 int32 block_ptr = ListHeads[ListIndex];
171 return ListBlocks[block_ptr + 1];
172 }
173
174
179 GEOMETRYCORE_API bool Contains(int32 ListIndex, int32 Value) const;
180
181
186 template<typename IntToBoolFunc>
187 inline int32 Find(int32 ListIndex, const IntToBoolFunc& PredicateFunc, int32 InvalidValue = -1) const
188 {
189 int32 block_ptr = ListHeads[ListIndex];
190 if (block_ptr != NullValue)
191 {
192 int32 N = ListBlocks[block_ptr];
193 if (N < BLOCKSIZE)
194 {
195 int32 iEnd = block_ptr + N;
196 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
197 {
199 if (PredicateFunc(Value))
200 {
201 return Value;
202 }
203 }
204 }
205 else
206 {
207 // we spilled to linked list, have to iterate through it as well
208 int32 iEnd = block_ptr + BLOCKSIZE;
209 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
210 {
212 if (PredicateFunc(Value))
213 {
214 return Value;
215 }
216 }
217 int32 cur_ptr = ListBlocks[block_ptr + BLOCK_LIST_OFFSET];
218 while (cur_ptr != NullValue)
219 {
220 int32 Value = LinkedListElements[cur_ptr];
221 if (PredicateFunc(Value))
222 {
223 return Value;
224 }
225 cur_ptr = LinkedListElements[cur_ptr + 1];
226 }
227 }
228 }
229 return InvalidValue;
230 }
231
232
233
238 template<typename IntToBoolFunc>
239 inline bool Replace(int32 ListIndex, const IntToBoolFunc& PredicateFunc, int32 NewValue)
240 {
241 int32 block_ptr = ListHeads[ListIndex];
242 if (block_ptr != NullValue)
243 {
244 int32 N = ListBlocks[block_ptr];
245 if (N < BLOCKSIZE)
246 {
247 int32 iEnd = block_ptr + N;
248 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
249 {
251 if (PredicateFunc(Value))
252 {
253 ListBlocks[i] = NewValue;
254 return true;
255 }
256 }
257 }
258 else
259 {
260 // we spilled to linked list, have to iterate through it as well
261 int32 iEnd = block_ptr + BLOCKSIZE;
262 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
263 {
265 if (PredicateFunc(Value))
266 {
267 ListBlocks[i] = NewValue;
268 return true;
269 }
270 }
271 int32 cur_ptr = ListBlocks[block_ptr + BLOCK_LIST_OFFSET];
272 while (cur_ptr != NullValue)
273 {
274 int32 Value = LinkedListElements[cur_ptr];
275 if (PredicateFunc(Value))
276 {
277 LinkedListElements[cur_ptr] = NewValue;
278 return true;
279 }
280 cur_ptr = LinkedListElements[cur_ptr + 1];
281 }
282 }
283 }
284 return false;
285 }
286
287
288
292 template<typename IntToVoidFunc>
293 inline void Enumerate(int32 ListIndex, const IntToVoidFunc& ApplyFunc) const
294 {
295 int32 block_ptr = ListHeads[ListIndex];
296 if (block_ptr != NullValue)
297 {
298 int32 N = ListBlocks[block_ptr];
299 if (N < BLOCKSIZE)
300 {
301 int32 iEnd = block_ptr + N;
302 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
303 {
305 }
306 }
307 else
308 {
309 // we spilled to linked list, have to iterate through it as well
310 int32 iEnd = block_ptr + BLOCKSIZE;
311 for (int32 i = block_ptr + 1; i <= iEnd; ++i)
312 {
314 }
315 int32 cur_ptr = ListBlocks[block_ptr + BLOCK_LIST_OFFSET];
316 while (cur_ptr != NullValue)
317 {
319 cur_ptr = LinkedListElements[cur_ptr + 1];
320 }
321 }
322 }
323 }
324
331 void AppendWithElementOffset(const FSmallListSet& Other, int32 ElementOffset);
332
337 bool EnumerateEarlyOut(int32 ListIndex, TFunctionRef<bool(int32)> ApplyFunc) const;
338
347 {
348 Set.Serialize(Ar, false, false);
349 return Ar;
350 }
351
358 GEOMETRYCORE_API void Serialize(FArchive& Ar, bool bCompactData, bool bUseCompression);
359
360 friend bool operator==(const FSmallListSet& Lhs, const FSmallListSet& Rhs)
361 {
362 if (Lhs.Size() != Rhs.Size())
363 {
364 return false;
365 }
366
367 for (int32 ListIndex = 0, ListNum = Lhs.Size(); ListIndex < ListNum; ++ListIndex)
368 {
369 if (Lhs.GetCount(ListIndex) != Rhs.GetCount(ListIndex))
370 {
371 return false;
372 }
373
374 ValueIterator ItLhs = Lhs.BeginValues(ListIndex);
375 ValueIterator ItRhs = Rhs.BeginValues(ListIndex);
376 const ValueIterator ItLhsEnd = Lhs.EndValues(ListIndex);
377 const ValueIterator ItRhsEnd = Rhs.EndValues(ListIndex);
378 while (ItLhs != ItLhsEnd && ItRhs != ItRhsEnd)
379 {
380 if (*ItLhs != *ItRhs)
381 {
382 return false;
383 }
384 ++ItLhs;
385 ++ItRhs;
386 }
387 if (ItLhs != ItLhsEnd || ItRhs != ItRhsEnd)
388 {
389 return false;
390 }
391 }
392
393 return true;
394 }
395
396 friend bool operator!=(const FSmallListSet& Lhs, const FSmallListSet& Rhs)
397 {
398 return !(Lhs == Rhs);
399 }
400
401 //
402 // iterator support
403 //
404
405
406 friend class ValueIterator;
407 friend class BaseValueIterator;
408
413 {
414 public:
416 {
417 ListSet = nullptr;
418 ListIndex = 0;
419 }
420
421 inline bool operator==(const BaseValueIterator& Other) const
422 {
423 return ListSet == Other.ListSet && ListIndex == Other.ListIndex;
424 }
425 inline bool operator!=(const BaseValueIterator& Other) const
426 {
427 return ListSet != Other.ListSet || ListIndex != Other.ListIndex || iCur != Other.iCur || cur_ptr != Other.cur_ptr;
428 }
429
430 protected:
431 inline void GotoNext()
432 {
433 if (N == 0)
434 {
435 SetToEnd();
436 return;
437 }
439 }
440
441 inline void GotoNextOverflow()
442 {
443 if (iCur <= iEnd)
444 {
446 iCur++;
447 }
448 else if (cur_ptr != NullValue)
449 {
452 }
453 else
454 {
455 SetToEnd();
456 }
457 }
458
462 bool is_end)
463 {
464 this->ListSet = ListSetIn;
465 this->ListIndex = ListIndex;
466 if (is_end)
467 {
468 SetToEnd();
469 }
470 else
471 {
474 {
476 iEnd = (N < BLOCKSIZE) ? (block_ptr + N) : (block_ptr + BLOCKSIZE);
477 iCur = block_ptr + 1;
479 GotoNext();
480 }
481 else
482 {
483 SetToEnd();
484 }
485 }
486 }
487
488 inline void SetToEnd()
489 {
491 N = 0;
492 iCur = -1;
493 cur_ptr = -1;
494 }
495
504 friend class FSmallListSet;
505 };
506
507
512 {
513 public:
515
516 inline int32 operator*() const
517 {
518 return cur_value;
519 }
520
521 inline const ValueIterator& operator++() // prefix
522 {
523 this->GotoNext();
524 return *this;
525 }
526
527 protected:
530
531 friend class FSmallListSet;
532 };
533
537 inline ValueIterator BeginValues(int32 ListIndex) const
538 {
539 return ValueIterator(this, ListIndex, false);
540 }
541
545 inline ValueIterator EndValues(int32 ListIndex) const
546 {
547 return ValueIterator(this, ListIndex, true);
548 }
549
554 {
555 public:
560 {
561 this->ListSet = ListSetIn;
562 this->ListIndex = ListIndex;
563 }
566 };
567
571 inline ValueEnumerable Values(int32 ListIndex) const
572 {
573 return ValueEnumerable(this, ListIndex);
574 }
575
576
577
578
579
580
581 //
582 // mapped iterator support - mapped iterator applies an arbitrary function to the iterator value
583 //
584
586
592 {
593 public:
595 {
596 MapFunc = [](int32 value) { return value; };
597 }
598
599 inline int32 operator*() const
600 {
601 return MapFunc(cur_value);
602 }
603
604 inline const MappedValueIterator& operator++() // prefix
605 {
606 this->GotoNext();
607 return *this;
608 }
609
610 protected:
616
618 friend class FSmallListSet;
619 };
620
624 inline MappedValueIterator BeginMappedValues(int32 ListIndex, const TFunction<int32(int32)>& MapFunc) const
625 {
626 return MappedValueIterator(this, ListIndex, false, MapFunc);
627 }
628
632 inline MappedValueIterator EndMappedValues(int32 ListIndex, const TFunction<int32(int32)>& MapFunc) const
633 {
634 return MappedValueIterator(this, ListIndex, true, MapFunc);
635 }
636
656
660 inline MappedValueEnumerable MappedValues(int32 ListIndex, TFunction<int32(int32)> MapFunc) const
661 {
662 return MappedValueEnumerable(this, ListIndex, MapFunc);
663 }
664
665
666
667
668
669
670
671protected:
672
673
674 // grab a block from the free list, or allocate a new one
676
677 // push a link-node onto the free list
678 inline void AddFreeLink(int32 ptr)
679 {
681 FreeHeadIndex = ptr;
682 }
683
684
685 // remove val from the linked-list attached to block_ptr
687
688
689public:
690 inline FString MemoryUsage() const
691 {
692 return FString::Printf(TEXT("ListSize %zu Blocks Count %d Free %zu Mem %zukb Linked Mem %zukb"),
694 ListBlocks.GetLength(), (LinkedListElements.GetLength() * sizeof(int32) / 1024));
695 }
696
701
702};
703
704
705} // end namespace UE::Geometry
706} // end namespace UE
#define checkSlow(expr)
Definition AssertionMacros.h:332
#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
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FORCEINLINE uint32 ToIndex(FHairStrandsTiles::ETileType Type)
Definition HairStrandsData.h:93
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition Archive.h:1208
virtual void Serialize(void *V, int64 Length)
Definition Archive.h:1689
Definition AssetRegistryState.h:50
Definition AndroidPlatformMisc.h:14
int32 N
Definition SmallListSet.h:499
const FSmallListSet * ListSet
Definition SmallListSet.h:496
int32 iCur
Definition SmallListSet.h:501
bool operator!=(const BaseValueIterator &Other) const
Definition SmallListSet.h:425
BaseValueIterator(const FSmallListSet *ListSetIn, int32 ListIndex, bool is_end)
Definition SmallListSet.h:459
int32 ListIndex
Definition SmallListSet.h:497
int32 block_ptr
Definition SmallListSet.h:498
bool operator==(const BaseValueIterator &Other) const
Definition SmallListSet.h:421
void SetToEnd()
Definition SmallListSet.h:488
int32 iEnd
Definition SmallListSet.h:500
void GotoNextOverflow()
Definition SmallListSet.h:441
void GotoNext()
Definition SmallListSet.h:431
int32 cur_value
Definition SmallListSet.h:503
int32 cur_ptr
Definition SmallListSet.h:502
BaseValueIterator()
Definition SmallListSet.h:415
MappedValueEnumerable(const FSmallListSet *ListSetIn, int32 ListIndex, TFunction< int32(int32)> MapFunc)
Definition SmallListSet.h:647
FSmallListSet::MappedValueIterator begin() const
Definition SmallListSet.h:653
int32 ListIndex
Definition SmallListSet.h:644
const FSmallListSet * ListSet
Definition SmallListSet.h:643
MappedValueEnumerable()
Definition SmallListSet.h:646
TFunction< int32(int32)> MapFunc
Definition SmallListSet.h:645
FSmallListSet::MappedValueIterator end() const
Definition SmallListSet.h:654
const MappedValueIterator & operator++()
Definition SmallListSet.h:604
MappedValueIterator(const FSmallListSet *ListSetIn, int32 ListIndex, bool is_end, TFunction< int32(int32)> MapFuncIn)
Definition SmallListSet.h:611
MappedValueIterator()
Definition SmallListSet.h:594
TFunction< int32(int32)> MapFunc
Definition SmallListSet.h:617
int32 operator*() const
Definition SmallListSet.h:599
const FSmallListSet * ListSet
Definition SmallListSet.h:556
int32 ListIndex
Definition SmallListSet.h:557
FSmallListSet::ValueIterator end() const
Definition SmallListSet.h:565
ValueEnumerable()
Definition SmallListSet.h:558
FSmallListSet::ValueIterator begin() const
Definition SmallListSet.h:564
ValueEnumerable(const FSmallListSet *ListSetIn, int32 ListIndex)
Definition SmallListSet.h:559
Definition SmallListSet.h:512
ValueIterator(const FSmallListSet *ListSetIn, int32 ListIndex, bool is_end)
Definition SmallListSet.h:528
int32 operator*() const
Definition SmallListSet.h:516
ValueIterator()
Definition SmallListSet.h:514
const ValueIterator & operator++()
Definition SmallListSet.h:521
Definition SmallListSet.h:36
GEOMETRYCORE_API void ResizeAndAllocateBlocks(int32 NewSize)
Definition SmallListSet.cpp:22
MappedValueIterator EndMappedValues(int32 ListIndex, const TFunction< int32(int32)> &MapFunc) const
Definition SmallListSet.h:632
static constexpr int32 BLOCK_LIST_OFFSET
Definition SmallListSet.h:44
GEOMETRYCORE_API void Move(int32 FromIndex, int32 ToIndex)
Definition SmallListSet.cpp:293
GEOMETRYCORE_API void AllocateAt(int32 ListIndex)
Definition SmallListSet.cpp:44
GEOMETRYCORE_API int32 AllocateBlock()
Definition SmallListSet.cpp:441
TDynamicVector< int32 > LinkedListElements
Definition SmallListSet.h:65
MappedValueIterator BeginMappedValues(int32 ListIndex, const TFunction< int32(int32)> &MapFunc) const
Definition SmallListSet.h:624
GEOMETRYCORE_API void Insert(int32 ListIndex, int32 Value)
Definition SmallListSet.cpp:195
void Reset()
Definition SmallListSet.h:94
TDynamicVector< int32 > ListHeads
Definition SmallListSet.h:47
friend FArchive & operator<<(FArchive &Ar, FSmallListSet &Set)
Definition SmallListSet.h:346
GEOMETRYCORE_API bool Contains(int32 ListIndex, int32 Value) const
Definition SmallListSet.cpp:336
int32 FreeHeadIndex
Definition SmallListSet.h:68
size_t Size() const
Definition SmallListSet.h:75
int32 First(int32 ListIndex) const
Definition SmallListSet.h:167
friend bool operator==(const FSmallListSet &Lhs, const FSmallListSet &Rhs)
Definition SmallListSet.h:360
void Enumerate(int32 ListIndex, const IntToVoidFunc &ApplyFunc) const
Definition SmallListSet.h:293
SIZE_T GetByteCount() const
Definition SmallListSet.h:697
FString MemoryUsage() const
Definition SmallListSet.h:690
ValueEnumerable Values(int32 ListIndex) const
Definition SmallListSet.h:571
int32 AllocatedCount
Definition SmallListSet.h:59
bool Replace(int32 ListIndex, const IntToBoolFunc &PredicateFunc, int32 NewValue)
Definition SmallListSet.h:239
GEOMETRYCORE_API bool RemoveFromLinkedList(int32 block_ptr, int32 val)
Definition SmallListSet.cpp:459
bool IsAllocated(int32 ListIndex) const
Definition SmallListSet.h:113
MappedValueEnumerable MappedValues(int32 ListIndex, TFunction< int32(int32)> MapFunc) const
Definition SmallListSet.h:660
int32 Find(int32 ListIndex, const IntToBoolFunc &PredicateFunc, int32 InvalidValue=-1) const
Definition SmallListSet.h:187
bool EnumerateEarlyOut(int32 ListIndex, TFunctionRef< bool(int32)> ApplyFunc) const
Definition SmallListSet.cpp:398
static constexpr int32 NullValue
Definition SmallListSet.h:39
friend bool operator!=(const FSmallListSet &Lhs, const FSmallListSet &Rhs)
Definition SmallListSet.h:396
int32 GetCount(int32 ListIndex) const
Definition SmallListSet.h:155
ValueIterator BeginValues(int32 ListIndex) const
Definition SmallListSet.h:537
void AppendWithElementOffset(const FSmallListSet &Other, int32 ElementOffset)
Definition SmallListSet.cpp:122
TDynamicVector< int32 > ListBlocks
Definition SmallListSet.h:53
void Compact(int32 MaxListIndex)
Definition SmallListSet.cpp:64
GEOMETRYCORE_API void Resize(int32 NewSize)
Definition SmallListSet.cpp:9
void AddFreeLink(int32 ptr)
Definition SmallListSet.h:678
ValueIterator EndValues(int32 ListIndex) const
Definition SmallListSet.h:545
static constexpr int32 BLOCKSIZE
Definition SmallListSet.h:42
TDynamicVector< int32 > FreeBlocks
Definition SmallListSet.h:56
Definition DynamicVector.h:27
size_t GetByteCount() const
Definition DynamicVector.h:149
void Clear()
Definition DynamicVector.h:578
size_t GetLength() const
Definition DynamicVector.h:146
Definition AdvancedWidgetsModule.cpp:13