UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ChunkedArray.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"
11
13{
14 template <typename ChunkType, typename ElementType, uint32 NumElementsPerChunk>
16 {
17 ChunkType** Chunk;
20
21 [[nodiscard]] ElementType& operator*() const
22 {
23 return (*Chunk)->Elements[ElementIndex];
24 }
25
27 {
29 if (ElementIndex >= NumElementsPerChunk)
30 {
31 ElementIndex = 0;
32 ++Chunk;
33 }
34
35 ++Count;
36 }
37
38 [[nodiscard]] bool operator!=(const TChunkedArrayIterator& Rhs) const
39 {
40 return Count < Rhs.Count;
41 }
42 };
43}
44
45// Forward declarations
46
47template<typename InElementType, uint32 TargetBytesPerChunk, typename AllocatorType>
48class TChunkedArray;
49
50template <typename T, uint32 TargetBytesPerChunk, typename AllocatorType>
52
54template<typename InElementType, uint32 TargetBytesPerChunk = 16384, typename AllocatorType = FDefaultAllocator >
56{
57 using ElementType = InElementType;
58
59public:
60
64 {
65 // Compute the number of chunks needed.
66 const int32 NumChunks = (NumElements + NumElementsPerChunk - 1) / NumElementsPerChunk;
67
68 // Allocate the chunks.
69 Chunks.Empty(NumChunks);
70 for(int32 ChunkIndex = 0;ChunkIndex < NumChunks;ChunkIndex++)
71 {
72 Chunks.Add(new FChunk);
73 }
74 }
75
76private:
77 template <typename ArrayType>
78 inline static void Move(ArrayType& ToArray, ArrayType& FromArray)
79 {
80 ToArray.Chunks = (ChunksType&&)FromArray.Chunks;
81 ToArray.NumElements = FromArray.NumElements;
82 FromArray.NumElements = 0;
83 }
84
85public:
87 {
88 this->Move(*this, Other);
89 }
90
92 {
93 if (this != &Other)
94 {
95 this->Move(*this, Other);
96 }
97
98 return *this;
99 }
100
102 {
103 UE_STATIC_ASSERT_WARN(TIsTriviallyRelocatable_V<InElementType>, "TChunkedArray can only be used with trivially relocatable types");
104 }
105
106 [[nodiscard]] TChunkedArray(const TChunkedArray&) = default;
108
110 // Start - intrusive TOptional<TChunkedArray> state //
112 constexpr static bool bHasIntrusiveUnsetOptionalState = true;
114
120 {
121 return NumElements == -1;
122 }
124 // End - intrusive TOptional<TChunkedArray> state //
126
127 // Accessors.
128 [[nodiscard]] ElementType& operator()(int32 ElementIndex)
129 {
130 const uint32 ChunkIndex = ElementIndex / NumElementsPerChunk;
131 const uint32 ChunkElementIndex = ElementIndex % NumElementsPerChunk;
132 return Chunks[ChunkIndex].Elements[ChunkElementIndex];
133 }
134 [[nodiscard]] const ElementType& operator()(int32 ElementIndex) const
135 {
136 const int32 ChunkIndex = ElementIndex / NumElementsPerChunk;
137 const int32 ChunkElementIndex = ElementIndex % NumElementsPerChunk;
138 return Chunks[ChunkIndex].Elements[ChunkElementIndex];
139 }
140 [[nodiscard]] ElementType& operator[](int32 ElementIndex)
141 {
142 const uint32 ChunkIndex = ElementIndex / NumElementsPerChunk;
143 const uint32 ChunkElementIndex = ElementIndex % NumElementsPerChunk;
144 return Chunks[ChunkIndex].Elements[ChunkElementIndex];
145 }
146 [[nodiscard]] const ElementType& operator[](int32 ElementIndex) const
147 {
148 const int32 ChunkIndex = ElementIndex / NumElementsPerChunk;
149 const int32 ChunkElementIndex = ElementIndex % NumElementsPerChunk;
150 return Chunks[ChunkIndex].Elements[ChunkElementIndex];
151 }
152
159 [[nodiscard]] bool IsEmpty() const
160 {
161 return NumElements == 0;
162 }
163
164 [[nodiscard]] int32 Num() const
165 {
166 return NumElements;
167 }
168
170 {
171 return Chunks.GetAllocatedSize();
172 }
173
183 {
184 return Index >= 0 && Index < NumElements;
185 }
186
193 int32 AddElement( const ElementType& Item )
194 {
195 new(*this) ElementType(Item);
196 return this->NumElements - 1;
197 }
198
205 template <typename... ArgsType>
207 {
208 new(*this) ElementType(Forward<ArgsType>(Args)...);
209 return this->NumElements - 1;
210 }
211
219 {
220 if( (UPTRINT*)this != (UPTRINT*)&Other )
221 {
222 for( const auto& It : Other )
223 {
224 AddElement(It);
225 }
226 }
227 return *this;
228 }
229
231 {
232 if( (UPTRINT*)this != (UPTRINT*)&Other )
233 {
234 for( int32 Index = 0; Index < Other.Num(); ++Index )
235 {
237 }
238 }
239 return *this;
240 }
241
243 {
244 check(Count>=0);
246
247 const int32 OldNum = NumElements;
251 for (int32 NumChunks = Chunks.Num(); NumChunks < NewNumChunks; ++NumChunks)
252 {
253 Chunks.Add(new FChunk);
254 }
255
256 return OldNum;
257 }
258
259 template<typename OtherAllocator>
277
278 template<typename OtherAllocator>
280 {
281 if (NumElements > 0)
282 {
284 DestinationArray.AddUninitialized(NumElements);
286
287 for (int32 ChunkIndex = 0; ChunkIndex < Chunks.Num(); ChunkIndex++)
288 {
289 const int32 NumElementsInCurrentChunk = FMath::Min<int32>(NumElements - ChunkIndex * NumElementsPerChunk, NumElementsPerChunk);
293 }
294
295 Empty();
296 }
297 }
298
299 void Empty( int32 Slack=0 )
300 {
301 // Compute the number of chunks needed.
302 const int32 NumChunks = (Slack + NumElementsPerChunk - 1) / NumElementsPerChunk;
303 Chunks.Empty(NumChunks);
304 NumElements = 0;
305 }
306
314 {
315 // Compute the number of chunks needed.
316 const int32 NumChunks = (Number + NumElementsPerChunk - 1) / NumElementsPerChunk;
317 Chunks.Reserve(NumChunks);
318 }
319
320 void Shrink()
321 {
322 Chunks.Shrink();
323 }
324
325protected:
326
327 enum { NumElementsPerChunk = TargetBytesPerChunk / sizeof(ElementType) };
328
330 struct FChunk
331 {
334 };
335
339
342
343private:
346
347public:
349 {
350 return FIterType{Chunks.GetData()};
351 }
352
354 {
355 return FConstIterType{Chunks.GetData()};
356 }
357
359 {
360 return FIterType{nullptr, uint32(NumElements)};
361 }
362
364 {
365 return FConstIterType{nullptr, uint32(NumElements)};
366 }
367};
368
369
370
371template <typename T,uint32 TargetBytesPerChunk, typename AllocatorType>
373{
374 check(Size == sizeof(T));
375 const int32 Index = ChunkedArray.Add(1);
376 return &ChunkedArray(Index);
377}
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define UE_STATIC_ASSERT_WARN(bExpression, Message)
Definition CoreMiscDefines.h:431
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
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Array.h:670
Definition ChunkedArray.h:56
ChunksType Chunks
Definition ChunkedArray.h:338
TChunkedArray & operator=(const TChunkedArray &)=default
void MoveToLinearArray(TArray< ElementType, OtherAllocator > &DestinationArray)
Definition ChunkedArray.h:279
FConstIterType end() const
Definition ChunkedArray.h:363
~TChunkedArray()
Definition ChunkedArray.h:101
static constexpr bool bHasIntrusiveUnsetOptionalState
Definition ChunkedArray.h:112
TChunkedArray & operator+=(const TArray< ElementType > &Other)
Definition ChunkedArray.h:218
int32 NumElements
Definition ChunkedArray.h:341
FConstIterType begin() const
Definition ChunkedArray.h:353
int32 Emplace(ArgsType &&... Args)
Definition ChunkedArray.h:206
TChunkedArray(const TChunkedArray &)=default
bool IsEmpty() const
Definition ChunkedArray.h:159
void Reserve(int32 Number)
Definition ChunkedArray.h:313
int32 Num() const
Definition ChunkedArray.h:164
TChunkedArray(TChunkedArray &&Other)
Definition ChunkedArray.h:86
void Shrink()
Definition ChunkedArray.h:320
TIndirectArray< FChunk, AllocatorType > ChunksType
Definition ChunkedArray.h:337
ElementType & operator[](int32 ElementIndex)
Definition ChunkedArray.h:140
const ElementType & operator()(int32 ElementIndex) const
Definition ChunkedArray.h:134
UE_FORCEINLINE_HINT bool IsValidIndex(int32 Index) const
Definition ChunkedArray.h:182
FIterType begin()
Definition ChunkedArray.h:348
TChunkedArray & operator+=(const TChunkedArray &Other)
Definition ChunkedArray.h:230
TChunkedArray(FIntrusiveUnsetOptionalState)
Definition ChunkedArray.h:115
int32 Add(int32 Count=1)
Definition ChunkedArray.h:242
int32 AddElement(const ElementType &Item)
Definition ChunkedArray.h:193
void CopyToLinearArray(TArray< ElementType, OtherAllocator > &DestinationArray)
Definition ChunkedArray.h:260
TChunkedArray & operator=(TChunkedArray &&Other)
Definition ChunkedArray.h:91
TChunkedArray(int32 InNumElements=0)
Definition ChunkedArray.h:62
@ NumElementsPerChunk
Definition ChunkedArray.h:327
SIZE_T GetAllocatedSize(void) const
Definition ChunkedArray.h:169
void Empty(int32 Slack=0)
Definition ChunkedArray.h:299
const ElementType & operator[](int32 ElementIndex) const
Definition ChunkedArray.h:146
bool operator==(FIntrusiveUnsetOptionalState) const
Definition ChunkedArray.h:119
FIterType end()
Definition ChunkedArray.h:358
ElementType & operator()(int32 ElementIndex)
Definition ChunkedArray.h:128
Definition IndirectArray.h:20
UE_FORCEINLINE_HINT void Reserve(int32 Number)
Definition IndirectArray.h:396
UE_FORCEINLINE_HINT int32 Num() const
Definition IndirectArray.h:94
UE_FORCEINLINE_HINT int32 Add(T *Item)
Definition IndirectArray.h:374
void Shrink()
Definition IndirectArray.h:181
void Empty(int32 Slack=0)
Definition IndirectArray.h:361
SIZE_T GetAllocatedSize() const
Definition IndirectArray.h:418
UE_FORCEINLINE_HINT T ** GetData()
Definition IndirectArray.h:104
Definition ChunkedArray.h:13
U16 Index
Definition radfft.cpp:71
Definition IntrusiveUnsetOptionalState.h:71
Definition ChunkedArray.h:331
ElementType Elements[NumElementsPerChunk]
Definition ChunkedArray.h:333
uint32 ElementIndex
Definition ChunkedArray.h:19
ChunkType ** Chunk
Definition ChunkedArray.h:17
bool operator!=(const TChunkedArrayIterator &Rhs) const
Definition ChunkedArray.h:38
void operator++()
Definition ChunkedArray.h:26
uint32 Count
Definition ChunkedArray.h:18
ElementType & operator*() const
Definition ChunkedArray.h:21