UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
StructArrayView.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "UObject/Class.h"
6#include "StructUtils.h"
8#include <type_traits>
9
11
19{
20 FStructArrayView() = default;
21
22 template<typename T>
24 : DataPtr(InArray.GetData())
25 , ScriptStruct(StaticStruct<std::remove_reference_t<T>>())
26 , ElementSize(sizeof(T))
27 , ArrayNum(InArray.Num())
28 {}
29
30 template<typename T>
32 : DataPtr(InArrayView.GetData())
33 , ScriptStruct(StaticStruct<std::remove_reference_t<T>>())
34 , ElementSize(sizeof(T))
35 , ArrayNum(InArrayView.Num())
36 {}
37
39 : DataPtr(InData)
40 , ScriptStruct(InScriptStruct)
41 , ElementSize(InElementSize)
42 , ArrayNum(InCount)
43 {
44 check((InData == nullptr) || ((InScriptStruct != nullptr) && (InElementSize > 0) && (InCount >= 0)));
45 check((InData != nullptr) || ((InScriptStruct == nullptr) && (InElementSize == 0) && (InCount == 0)));
46 }
47
49 : DataPtr(InData)
50 , ScriptStruct(&InScriptStruct)
51 , ElementSize(InScriptStruct.GetStructureSize())
52 , ArrayNum(InCount)
53 {
54 check(InCount >= 0);
55 check(InData != nullptr || InCount == 0);
56 }
57
58 UE_DEPRECATED(5.3, "Use constructor that takes a reference instead")
60 : DataPtr(InData)
61 , ScriptStruct(InScriptStruct)
62 , ElementSize(InScriptStruct->GetStructureSize())
63 , ArrayNum(InCount)
64 {
66 check(InCount >= 0);
67 check(InData != nullptr || InCount == 0);
68 }
69
73 void CheckInvariants() const
74 {
75 checkSlow(ArrayNum >= 0);
76 }
77
84 {
85 checkf((Index >= 0) & (Index < ArrayNum), TEXT("Array index out of bounds: %d from an array of size %d"), Index, ArrayNum);
86 }
87
95 void SliceRangeCheck(const int32 Index, const int32 InNum) const
96 {
97 checkf(Index >= 0, TEXT("Invalid index (%d)"), Index);
98 checkf(InNum >= 0, TEXT("Invalid count (%d)"), InNum);
99 checkf(Index + InNum <= ArrayNum, TEXT("Range (index: %d, count: %d) lies outside the view of %d elements"), Index, InNum, ArrayNum);
100 }
101
109 bool IsValidIndex(const int32 Index) const
110 {
111 return (Index >= 0) && (Index < ArrayNum);
112 }
113
120 bool IsEmpty() const
121 {
122 return ArrayNum == 0;
123 }
124
130 void* GetData() const
131 {
132 return DataPtr;
133 }
134
141 void* GetDataAt(const int32 Index) const
142 {
144 return (uint8*)DataPtr + ((SIZE_T)Index * ElementSize);
145 }
146
147 UE_DEPRECATED(5.3, "Use GetDataAt() instead")
148 void* GetMutableDataAt(const int32 Index) const { return GetDataAt(Index); }
149
156 {
157 return ElementSize;
158 }
159
160 UE_DEPRECATED(5.3, "Removed to bring in to line with ArrayView, use GetTypeSize() instead")
161 SIZE_T GetElementSize() const { return ElementSize; }
162
168 int32 Num() const { return ArrayNum; }
169
170 UE_DEPRECATED(5.3, "Use GetScriptStruct() instead")
171 const UScriptStruct& GetElementType() const { check(ScriptStruct); return *ScriptStruct; }
172
173 UE_DEPRECATED(5.3, "Use GetScriptStruct() instead")
174 const UScriptStruct& GetFragmentType() const { check(ScriptStruct); return *ScriptStruct; }
175
177 const UScriptStruct* GetScriptStruct() const { return ScriptStruct; }
178
187 template<typename T>
188 T* GetPtrAt(const int32 Index) const
189 {
190 return UE::StructUtils::GetStructPtr<T>(ScriptStruct, GetDataAt(Index)); // GetDataAt() calls RangeCheck().
191 }
192
200 template<typename T>
201 T& GetAt(const int32 Index) const
202 {
203 return UE::StructUtils::GetStructRef<T>(ScriptStruct, GetDataAt(Index)); // GetDataAt() calls RangeCheck().
204 }
205
206 template<typename T>
207 UE_DEPRECATED(5.3, "Use GetAt() instead!")
208 const T& GetElementAt(const int32 Index) const
209 {
210 return *((T*)GetDataAt(Index));
211 }
212
213 template<typename T>
214 UE_DEPRECATED(5.3, "Use GetAt() instead!")
215 const T& GetElementAtChecked(const int32 Index) const
216 {
217 check(TBaseStructure<T>::Get() == &ScriptStruct);
218 return *((T*)GetDataAt(Index));
219 }
220
221 template<typename T>
222 UE_DEPRECATED(5.3, "Use GetAt() instead!")
224 {
225 return *((T*)GetDataAt(Index));
226 }
227
228 template<typename T>
229 UE_DEPRECATED(5.3, "Use GetAt() instead!")
231 {
232 check(TBaseStructure<T>::Get() == &ScriptStruct);
233 return *((T*)GetDataAt(Index));
234 }
235
242 {
243 return FStructView(ScriptStruct, (uint8*)GetDataAt(Index)); // GetDataAt() calls RangeCheck().
244 }
245
254 template<typename T>
255 T& Last(const int32 IndexFromTheEnd = 0) const
256 {
257 return GetAt<T>(ArrayNum - IndexFromTheEnd - 1);
258 }
259
271 {
273 return FStructArrayView(ScriptStruct, GetDataAt(Index), ElementSize, InNum);
274 }
275
278 {
279 return FStructArrayView(ScriptStruct, DataPtr, ElementSize, FMath::Clamp(Count, 0, ArrayNum));
280 }
281
284 {
285 return FStructArrayView(ScriptStruct, DataPtr, ElementSize, FMath::Clamp(ArrayNum - Count, 0, ArrayNum));
286 }
287
290 {
291 const int32 OutLen = FMath::Clamp(Count, 0, ArrayNum);
292 return FStructArrayView(ScriptStruct, GetDataAt(ArrayNum - OutLen), ElementSize, OutLen);
293 }
294
297 {
298 const int32 OutLen = FMath::Clamp(ArrayNum - Count, 0, ArrayNum);
299 return FStructArrayView(ScriptStruct, GetDataAt(ArrayNum - OutLen), ElementSize, OutLen);
300 }
301
308
311 {
312 *this = Left(Count);
313 }
314
317 {
318 *this = LeftChop(Count);
319 }
320
323 {
324 *this = Right(Count);
325 }
326
329 {
330 *this = RightChop(Count);
331 }
332
335 {
336 *this = Mid(Position, Count);
337 }
338
340 {
342 : Owner(&InOwner)
343 , Index(InIndex)
344 {}
345
347 {
348 ++Index;
349 return *this;
350 }
351
353 {
354 return (*Owner)[Index];
355 }
356
357 inline bool operator == (const FIterator& Other) const
358 {
359 return Owner == Other.Owner
360 && Index == Other.Index;
361 }
362
364 {
365 return !(*this == Other);
366 }
367
368 private:
369 const FStructArrayView* Owner = nullptr;
371 };
372
374 UE_FORCEINLINE_HINT FIterator begin() const { return FIterator(*this, 0); }
375 UE_FORCEINLINE_HINT FIterator end() const { return FIterator(*this, Num()); }
376
378 UE_FORCEINLINE_HINT void Swap(const int32 Index1, const int32 Index2)
379 {
380 FMemory::Memswap(GetDataAt(Index1), GetDataAt(Index2), ElementSize); // GetDataAt() calls RangeCheck().
381 }
382
383private:
384 void* DataPtr = nullptr;
385 const UScriptStruct* ScriptStruct = nullptr;
386 uint32 ElementSize = 0;
387 int32 ArrayNum = 0;
388};
389
391
398{
400
401 template<typename T>
403 : DataPtr(InArray.GetData())
404 , ScriptStruct(StaticStruct<std::remove_reference_t<T>>())
405 , ElementSize(sizeof(T))
406 , ArrayNum(InArray.Num())
407 {}
408
409 template<typename T>
411 : DataPtr(InArrayView.GetData())
412 , ScriptStruct(StaticStruct<std::remove_reference_t<T>>())
413 , ElementSize(sizeof(T))
414 , ArrayNum(InArrayView.Num())
415 {}
416
418 : DataPtr(Src.GetData())
419 , ScriptStruct(Src.GetScriptStruct())
420 , ElementSize(Src.GetTypeSize())
421 , ArrayNum(Src.Num())
422 {}
423
425 : DataPtr(InData)
426 , ScriptStruct(InScriptStruct)
427 , ElementSize(InElementSize)
428 , ArrayNum(InCount)
429 {
430 check((InData == nullptr) || ((InScriptStruct != nullptr) && (InElementSize > 0) && (InCount >= 0)));
431 check((InData != nullptr) || ((InScriptStruct == nullptr) && (InElementSize == 0) && (InCount == 0)));
432 }
433
435 : DataPtr(InData)
436 , ScriptStruct(&InScriptStruct)
437 , ElementSize(InScriptStruct.GetStructureSize())
438 , ArrayNum(InCount)
439 {
440 check(InCount >= 0);
441 check(InData != nullptr || InCount == 0);
442 }
443
449
453 void CheckInvariants() const
454 {
455 checkSlow(ArrayNum >= 0);
456 }
457
464 {
465 checkf((Index >= 0) & (Index < ArrayNum), TEXT("Array index out of bounds: %d from an array of size %d"), Index, ArrayNum);
466 }
467
476 {
477 checkf(Index >= 0, TEXT("Invalid index (%d)"), Index);
478 checkf(InNum >= 0, TEXT("Invalid count (%d)"), InNum);
479 checkf(Index + InNum <= ArrayNum, TEXT("Range (index: %d, count: %d) lies outside the view of %d elements"), Index, InNum, ArrayNum);
480 }
481
490 {
491 return (Index >= 0) && (Index < ArrayNum);
492 }
493
500 bool IsEmpty() const
501 {
502 return ArrayNum == 0;
503 }
504
510 const void* GetData() const
511 {
512 return DataPtr;
513 }
514
521 const void* GetDataAt(const int32 Index) const
522 {
524 return (uint8*)DataPtr + (SIZE_T)Index * ElementSize;
525 }
526
533 {
534 return ElementSize;
535 }
536
542 int32 Num() const { return ArrayNum; }
543
545 const UScriptStruct* GetScriptStruct() const { return ScriptStruct; }
546
555 template<typename T>
556 requires (std::is_const_v<T>)
557 constexpr T* GetPtrAt(const int32 Index) const
558 {
559 return UE::StructUtils::GetStructPtr<T>(ScriptStruct, GetDataAt(Index)); // GetDataAt() calls RangeCheck().
560 }
561
569 template<typename T>
570 requires (std::is_const_v<T>)
571 constexpr T& GetAt(const int32 Index) const
572 {
573 return UE::StructUtils::GetStructRef<T>(ScriptStruct, GetDataAt(Index)); // GetDataAt() calls RangeCheck().
574 }
575
582 {
583 return FConstStructView(ScriptStruct, (const uint8*)GetDataAt(Index)); // GetDataAt() calls RangeCheck().
584 }
585
594 template<typename T>
595 requires (std::is_const_v<T>)
596 constexpr T& Last(int32 IndexFromTheEnd = 0) const
597 {
598 return GetAt<T>(ArrayNum - IndexFromTheEnd - 1);
599 }
600
612 {
614 return FConstStructArrayView(ScriptStruct, GetDataAt(Index), ElementSize, InNum);
615 }
616
619 {
620 return FConstStructArrayView(ScriptStruct, DataPtr, ElementSize, FMath::Clamp(Count, 0, ArrayNum));
621 }
622
625 {
626 return FConstStructArrayView(ScriptStruct, DataPtr, ElementSize, FMath::Clamp(ArrayNum - Count, 0, ArrayNum));
627 }
628
631 {
632 const int32 OutLen = FMath::Clamp(Count, 0, ArrayNum);
633 return FConstStructArrayView(ScriptStruct, GetDataAt(ArrayNum - OutLen), ElementSize, OutLen);
634 }
635
638 {
639 const int32 OutLen = FMath::Clamp(ArrayNum - Count, 0, ArrayNum);
640 return FConstStructArrayView(ScriptStruct, GetDataAt(ArrayNum - OutLen), ElementSize, OutLen);
641 }
642
649
652 {
653 *this = Left(Count);
654 }
655
658 {
659 *this = LeftChop(Count);
660 }
661
664 {
665 *this = Right(Count);
666 }
667
670 {
671 *this = RightChop(Count);
672 }
673
676 {
677 *this = Mid(Position, Count);
678 }
679
681 {
686
688 {
689 ++Index;
690 return *this;
691 }
692
694 {
695 return (*Owner)[Index];
696 }
697
698 inline bool operator == (const FIterator& Other) const
699 {
700 return Owner == Other.Owner
701 && Index == Other.Index;
702 }
703
705 {
706 return !(*this == Other);
707 }
708
709 private:
710 const FConstStructArrayView* Owner = nullptr;
712 };
713
715 UE_FORCEINLINE_HINT FIterator begin() const { return FIterator(*this, 0); }
716 UE_FORCEINLINE_HINT FIterator end() const { return FIterator(*this, Num()); }
717
718private:
719 const void* DataPtr = nullptr;
720 const UScriptStruct* ScriptStruct = nullptr;
721 uint32 ElementSize = 0;
722 int32 ArrayNum = 0;
723};
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 checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#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
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UScriptStruct * StaticStruct()
Definition ReflectedTypeAccessors.h:18
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ArrayView.h:139
Definition Array.h:670
Definition Class.h:1720
void CalcMidIndexAndCount(int32 ArrayNum, int32 &InOutIndex, int32 &InOutCount)
Definition StructUtils.h:109
U16 Index
Definition radfft.cpp:71
Definition StructArrayView.h:681
FIterator(const FConstStructArrayView &InOwner, int32 InIndex)
Definition StructArrayView.h:682
bool operator==(const FIterator &Other) const
Definition StructArrayView.h:698
FConstStructView operator*() const
Definition StructArrayView.h:693
UE_FORCEINLINE_HINT bool operator!=(const FIterator &Other) const
Definition StructArrayView.h:704
FIterator & operator++()
Definition StructArrayView.h:687
Definition StructArrayView.h:398
int32 Num() const
Definition StructArrayView.h:542
FConstStructArrayView()=default
void SliceRangeCheck(int32 Index, int32 InNum) const
Definition StructArrayView.h:475
void LeftChopInline(const int32 Count)
Definition StructArrayView.h:657
const void * GetData() const
Definition StructArrayView.h:510
FConstStructArrayView LeftChop(const int32 Count) const
Definition StructArrayView.h:624
bool IsEmpty() const
Definition StructArrayView.h:500
constexpr T * GetPtrAt(const int32 Index) const
Definition StructArrayView.h:557
UE_FORCEINLINE_HINT FIterator begin() const
Definition StructArrayView.h:715
FConstStructArrayView(const UScriptStruct &InScriptStruct, const void *InData, const int32 InCount)
Definition StructArrayView.h:434
FConstStructArrayView(TArray< T > &InArray)
Definition StructArrayView.h:402
UE_FORCEINLINE_HINT FIterator end() const
Definition StructArrayView.h:716
FConstStructArrayView Left(const int32 Count) const
Definition StructArrayView.h:618
constexpr T & Last(int32 IndexFromTheEnd=0) const
Definition StructArrayView.h:596
FConstStructView operator[](int32 Index) const
Definition StructArrayView.h:581
UE_FORCEINLINE_HINT uint32 GetTypeSize()
Definition StructArrayView.h:532
constexpr T & GetAt(const int32 Index) const
Definition StructArrayView.h:571
void RangeCheck(int32 Index) const
Definition StructArrayView.h:463
FConstStructArrayView(const FStructArrayView Src)
Definition StructArrayView.h:417
void CheckInvariants() const
Definition StructArrayView.h:453
const UScriptStruct * GetScriptStruct() const
Definition StructArrayView.h:545
const void * GetDataAt(const int32 Index) const
Definition StructArrayView.h:521
FConstStructArrayView Mid(int32 Index, int32 Count=TNumericLimits< int32 >::Max()) const
Definition StructArrayView.h:644
void RightChopInline(const int32 Count)
Definition StructArrayView.h:669
FConstStructArrayView RightChop(const int32 Count) const
Definition StructArrayView.h:637
bool IsValidIndex(int32 Index) const
Definition StructArrayView.h:489
FConstStructArrayView(const UScriptStruct *InScriptStruct, const void *InData, const uint32 InElementSize, const int32 InCount)
Definition StructArrayView.h:424
void RightInline(const int32 Count)
Definition StructArrayView.h:663
void MidInline(const int32 Position, const int32 Count=TNumericLimits< int32 >::Max())
Definition StructArrayView.h:675
FConstStructArrayView Slice(const int32 Index, const int32 InNum) const
Definition StructArrayView.h:611
void LeftInline(const int32 Count)
Definition StructArrayView.h:651
FConstStructArrayView(TArrayView< T > InArrayView)
Definition StructArrayView.h:410
FConstStructArrayView & operator=(const FStructArrayView StructArrayView)
Definition StructArrayView.h:444
FConstStructArrayView Right(const int32 Count) const
Definition StructArrayView.h:630
Definition StructView.h:217
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
static UE_FORCEINLINE_HINT void Memswap(void *Ptr1, void *Ptr2, SIZE_T Size)
Definition UnrealMemory.h:187
Definition StructArrayView.h:340
bool operator==(const FIterator &Other) const
Definition StructArrayView.h:357
FIterator & operator++()
Definition StructArrayView.h:346
FIterator(const FStructArrayView &InOwner, int32 InIndex)
Definition StructArrayView.h:341
UE_FORCEINLINE_HINT bool operator!=(const FIterator &Other) const
Definition StructArrayView.h:363
FStructView operator*() const
Definition StructArrayView.h:352
Definition StructArrayView.h:19
FStructArrayView()=default
const T & GetElementAt(const int32 Index) const
Definition StructArrayView.h:208
int32 Num() const
Definition StructArrayView.h:168
FStructArrayView Right(const int32 Count) const
Definition StructArrayView.h:289
SIZE_T GetElementSize() const
Definition StructArrayView.h:161
T & GetAt(const int32 Index) const
Definition StructArrayView.h:201
FStructArrayView Left(const int32 Count) const
Definition StructArrayView.h:277
void LeftChopInline(const int32 Count)
Definition StructArrayView.h:316
const UScriptStruct & GetFragmentType() const
Definition StructArrayView.h:174
const T & GetElementAtChecked(const int32 Index) const
Definition StructArrayView.h:215
FStructArrayView(const UScriptStruct *InScriptStruct, void *InData, const uint32 InElementSize, const int32 InCount)
Definition StructArrayView.h:38
FStructArrayView(TArrayView< T > InArrayView)
Definition StructArrayView.h:31
T & Last(const int32 IndexFromTheEnd=0) const
Definition StructArrayView.h:255
void RightChopInline(const int32 Count)
Definition StructArrayView.h:328
void MidInline(const int32 Position, const int32 Count=TNumericLimits< int32 >::Max())
Definition StructArrayView.h:334
bool IsValidIndex(const int32 Index) const
Definition StructArrayView.h:109
bool IsEmpty() const
Definition StructArrayView.h:120
FStructArrayView(TArray< T > &InArray)
Definition StructArrayView.h:23
FStructArrayView(const UScriptStruct &InScriptStruct, void *InData, const int32 InCount)
Definition StructArrayView.h:48
void RangeCheck(int32 Index) const
Definition StructArrayView.h:83
UE_FORCEINLINE_HINT FIterator end() const
Definition StructArrayView.h:375
void SliceRangeCheck(const int32 Index, const int32 InNum) const
Definition StructArrayView.h:95
FStructArrayView LeftChop(const int32 Count) const
Definition StructArrayView.h:283
FStructArrayView Slice(const int32 Index, const int32 InNum) const
Definition StructArrayView.h:270
UE_FORCEINLINE_HINT void Swap(const int32 Index1, const int32 Index2)
Definition StructArrayView.h:378
void RightInline(const int32 Count)
Definition StructArrayView.h:322
UE_FORCEINLINE_HINT FIterator begin() const
Definition StructArrayView.h:374
void CheckInvariants() const
Definition StructArrayView.h:73
T * GetPtrAt(const int32 Index) const
Definition StructArrayView.h:188
void LeftInline(const int32 Count)
Definition StructArrayView.h:310
void * GetMutableDataAt(const int32 Index) const
Definition StructArrayView.h:148
T & GetMutableElementAt(const int32 Index) const
Definition StructArrayView.h:223
void * GetDataAt(const int32 Index) const
Definition StructArrayView.h:141
T & GetMutableElementAtChecked(const int32 Index) const
Definition StructArrayView.h:230
const UScriptStruct * GetScriptStruct() const
Definition StructArrayView.h:177
FStructArrayView Mid(int32 Index, int32 Count=TNumericLimits< int32 >::Max()) const
Definition StructArrayView.h:303
const UScriptStruct & GetElementType() const
Definition StructArrayView.h:171
void * GetData() const
Definition StructArrayView.h:130
UE_FORCEINLINE_HINT uint32 GetTypeSize() const
Definition StructArrayView.h:155
FStructView operator[](const int32 Index) const
Definition StructArrayView.h:241
FStructArrayView RightChop(const int32 Count) const
Definition StructArrayView.h:296
Definition StructView.h:24
Definition Class.h:5288
Definition NumericLimits.h:41