// Copyright 2020 Phyronnaz #pragma once #include "CoreMinimal.h" #include "VoxelMinimal.h" #include "VoxelUtilities/VoxelBaseUtilities.h" template class alignas(Alignment) TVoxelStaticArray { public: using ElementType = T; TVoxelStaticArray() { } FORCEINLINE explicit TVoxelStaticArray(EForceInit) { for (auto& Element : *this) { new (&Element) T{}; } } template FORCEINLINE TVoxelStaticArray(TArgs... Args) { static_assert(sizeof...(Args) == Size, ""); SetFromVariadicArgs(Args...); } FORCEINLINE static constexpr uint32 Num() { return Size; } FORCEINLINE static constexpr uint32 GetTypeSize() { return sizeof(T); } FORCEINLINE void Memzero() { FMemory::Memzero(GetData(), Size * sizeof(T)); } FORCEINLINE T* RESTRICT GetData() { return reinterpret_cast(Data); } FORCEINLINE const T* RESTRICT GetData() const { return reinterpret_cast(Data); } template void CopyFromArray(const TArray& Array, bool bInitializeEnd = true) { check(Size >= Array.Num()); for (int32 Index = 0; Index < Array.Num(); Index++) { (*this)[Index] = Array[Index]; } if (bInitializeEnd) { for (int32 Index = Array.Num(); Index < Size; Index++) { (*this)[Index] = T{}; } } } FORCEINLINE T& operator[](int32 Index) { checkVoxelSlow(0 <= Index && Index < Size); return GetData()[Index]; } FORCEINLINE const T& operator[](int32 Index) const { checkVoxelSlow(0 <= Index && Index < Size); return GetData()[Index]; } operator TArray() const { return TArray(GetData(), Num()); } operator TArrayView() { return TArrayView(GetData(), Num()); } operator TArrayView() const { return TArrayView(GetData(), Num()); } FORCEINLINE T* begin() { return GetData(); } FORCEINLINE T* end() { return GetData() + Size; } FORCEINLINE const T* begin() const { return GetData(); } FORCEINLINE const T* end() const { return GetData() + Size; } template FORCEINLINE void SetFromVariadicArgs(T Arg, TArgs... Args) { static_assert(0 <= Index && Index < Size, ""); static_assert(sizeof...(Args) == Size - 1 - Index, ""); (*this)[Index] = Arg; SetFromVariadicArgs(Args...); } template FORCEINLINE void SetFromVariadicArgs(T Arg) { static_assert(Index == Size - 1, ""); (*this)[Index] = Arg; } private: uint8 Data[Size * sizeof(T)]; }; template struct TIsContiguousContainer> { enum { Value = true }; }; template class TVoxelStaticBitArray { public: TVoxelStaticBitArray() = default; TVoxelStaticBitArray(EForceInit) { Clear(); } void Clear() { Array.Memzero(); } FORCEINLINE void Set(uint32 Index) { checkVoxelSlow(Index < Size); Array[Index / 32] |= (1u << (Index % 32)); } FORCEINLINE void Clear(uint32 Index) { checkVoxelSlow(Index < Size); Array[Index / 32] &= ~(1u << (Index % 32)); } FORCEINLINE bool Test(uint32 Index) const { checkVoxelSlow(Index < Size); return Array[Index / 32] & (1u << (Index % 32)); } private: TVoxelStaticArray Array; };