// Copyright 2020 Phyronnaz #pragma once #include "CoreMinimal.h" #include "VoxelValue.h" #include "VoxelMaterial.h" namespace FVoxelUtilities { template struct TValuesMaterialsSelector; template<> struct TValuesMaterialsSelector { template static inline auto& Get(U& Object) { return Object.Values; } }; template<> struct TValuesMaterialsSelector { template static inline auto& Get(U& Object) { return Object.Materials; } }; template<> struct TValuesMaterialsSelector { template static inline auto& Get(U& Object) { return Object.Values; } }; template<> struct TValuesMaterialsSelector { template static inline auto& Get(U& Object) { return Object.Materials; } }; struct FTrueType { FORCEINLINE constexpr operator bool() const { return true; } }; struct FFalseType { FORCEINLINE constexpr operator bool() const { return false; } }; template void StaticBranch(bool bA, T Lambda) { if (bA) Lambda(FTrueType()); else Lambda(FFalseType()); } template void StaticBranch(bool bA, bool bB, TLambda Lambda) { const int32 Value = bA + 2 * bB; using T = FTrueType; using F = FFalseType; switch (Value) { case 0: Lambda(F(), F()); return; case 1: Lambda(T(), F()); return; case 2: Lambda(F(), T()); return; case 3: Lambda(T(), T()); return; default: checkVoxelSlow(false); return; } } template void StaticBranch(bool bA, bool bB, bool bC, TLambda Lambda) { const int32 Value = bA + 2 * bB + 4 * bC; using T = FTrueType; using F = FFalseType; switch (Value) { case 0: Lambda(F(), F(), F()); return; case 1: Lambda(T(), F(), F()); return; case 2: Lambda(F(), T(), F()); return; case 3: Lambda(T(), T(), F()); return; case 4: Lambda(F(), F(), T()); return; case 5: Lambda(T(), F(), T()); return; case 6: Lambda(F(), T(), T()); return; case 7: Lambda(T(), T(), T()); return; default: checkVoxelSlow(false); return; } } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// template struct TInteger { FORCEINLINE constexpr operator int32() const { return N; } }; template struct TStaticSwitch; #define VOXEL_STATIC_SWITCH_CASE(Index) case Index: Lambda(TInteger()); return; #define VOXEL_STATIC_SWITCH_CASE_1 VOXEL_STATIC_SWITCH_CASE(0) #define VOXEL_STATIC_SWITCH_CASE_2 VOXEL_STATIC_SWITCH_CASE_1 VOXEL_STATIC_SWITCH_CASE(1) #define VOXEL_STATIC_SWITCH_CASE_3 VOXEL_STATIC_SWITCH_CASE_2 VOXEL_STATIC_SWITCH_CASE(2) #define VOXEL_STATIC_SWITCH_CASE_4 VOXEL_STATIC_SWITCH_CASE_3 VOXEL_STATIC_SWITCH_CASE(3) #define VOXEL_STATIC_SWITCH_CASE_5 VOXEL_STATIC_SWITCH_CASE_4 VOXEL_STATIC_SWITCH_CASE(4) #define VOXEL_STATIC_SWITCH_CASE_6 VOXEL_STATIC_SWITCH_CASE_5 VOXEL_STATIC_SWITCH_CASE(5) #define VOXEL_STATIC_SWITCH_CASE_7 VOXEL_STATIC_SWITCH_CASE_6 VOXEL_STATIC_SWITCH_CASE(6) #define VOXEL_STATIC_SWITCH_CASE_8 VOXEL_STATIC_SWITCH_CASE_7 VOXEL_STATIC_SWITCH_CASE(7) #define VOXEL_STATIC_SWITCH_CASE_9 VOXEL_STATIC_SWITCH_CASE_8 VOXEL_STATIC_SWITCH_CASE(8) #define VOXEL_STATIC_SWITCH_CASE_10 VOXEL_STATIC_SWITCH_CASE_9 VOXEL_STATIC_SWITCH_CASE(9) #define VOXEL_STATIC_SWITCH_CASE_11 VOXEL_STATIC_SWITCH_CASE_10 VOXEL_STATIC_SWITCH_CASE(10) #define VOXEL_STATIC_SWITCH_CASE_12 VOXEL_STATIC_SWITCH_CASE_11 VOXEL_STATIC_SWITCH_CASE(11) #define VOXEL_STATIC_SWITCH_CASE_13 VOXEL_STATIC_SWITCH_CASE_12 VOXEL_STATIC_SWITCH_CASE(12) #define VOXEL_STATIC_SWITCH_CASE_14 VOXEL_STATIC_SWITCH_CASE_13 VOXEL_STATIC_SWITCH_CASE(13) #define VOXEL_STATIC_SWITCH_CASE_15 VOXEL_STATIC_SWITCH_CASE_14 VOXEL_STATIC_SWITCH_CASE(14) #define VOXEL_STATIC_SWITCH_CASE_16 VOXEL_STATIC_SWITCH_CASE_15 VOXEL_STATIC_SWITCH_CASE(15) #define VOXEL_STATIC_SWITCH_CASE_17 VOXEL_STATIC_SWITCH_CASE_16 VOXEL_STATIC_SWITCH_CASE(16) #define VOXEL_STATIC_SWITCH_CASE_18 VOXEL_STATIC_SWITCH_CASE_17 VOXEL_STATIC_SWITCH_CASE(17) #define VOXEL_STATIC_SWITCH_CASE_19 VOXEL_STATIC_SWITCH_CASE_18 VOXEL_STATIC_SWITCH_CASE(18) #define VOXEL_STATIC_SWITCH_CASE_20 VOXEL_STATIC_SWITCH_CASE_19 VOXEL_STATIC_SWITCH_CASE(19) #define VOXEL_STATIC_SWITCH_CASE_21 VOXEL_STATIC_SWITCH_CASE_20 VOXEL_STATIC_SWITCH_CASE(20) #define VOXEL_STATIC_SWITCH_CASE_22 VOXEL_STATIC_SWITCH_CASE_21 VOXEL_STATIC_SWITCH_CASE(21) #define VOXEL_STATIC_SWITCH_CASE_23 VOXEL_STATIC_SWITCH_CASE_22 VOXEL_STATIC_SWITCH_CASE(22) #define VOXEL_STATIC_SWITCH_CASE_24 VOXEL_STATIC_SWITCH_CASE_23 VOXEL_STATIC_SWITCH_CASE(23) #define VOXEL_STATIC_SWITCH_CASE_25 VOXEL_STATIC_SWITCH_CASE_24 VOXEL_STATIC_SWITCH_CASE(24) #define VOXEL_STATIC_SWITCH_CASE_26 VOXEL_STATIC_SWITCH_CASE_25 VOXEL_STATIC_SWITCH_CASE(25) #define VOXEL_STATIC_SWITCH_CASE_27 VOXEL_STATIC_SWITCH_CASE_26 VOXEL_STATIC_SWITCH_CASE(26) #define VOXEL_STATIC_SWITCH_CASE_28 VOXEL_STATIC_SWITCH_CASE_27 VOXEL_STATIC_SWITCH_CASE(27) #define VOXEL_STATIC_SWITCH_CASE_29 VOXEL_STATIC_SWITCH_CASE_28 VOXEL_STATIC_SWITCH_CASE(28) #define VOXEL_STATIC_SWITCH_CASE_30 VOXEL_STATIC_SWITCH_CASE_29 VOXEL_STATIC_SWITCH_CASE(29) #define VOXEL_STATIC_SWITCH_CASE_31 VOXEL_STATIC_SWITCH_CASE_30 VOXEL_STATIC_SWITCH_CASE(30) #define VOXEL_STATIC_SWITCH_CASE_32 VOXEL_STATIC_SWITCH_CASE_31 VOXEL_STATIC_SWITCH_CASE(31) #define VOXEL_STATIC_SWITCH(Index) \ template<> \ struct TStaticSwitch \ { \ template \ static void Switch(int32 Value, TLambda Lambda) \ { \ switch (Value) \ { \ VOXEL_STATIC_SWITCH_CASE_##Index \ default: ensureVoxelSlow(false); return; \ } \ } \ }; VOXEL_STATIC_SWITCH(4); VOXEL_STATIC_SWITCH(6); VOXEL_STATIC_SWITCH(8); VOXEL_STATIC_SWITCH(12); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// template struct THasForceInitConstructor { template static uint8 Test(X*); template static uint32 Test(...); static constexpr bool Value = sizeof(Test(nullptr)) == sizeof(uint8); }; // Works with void template typename TEnableIf::Value, T>::Type GetDefaultValue() { return T(); } template typename TEnableIf::Value, T>::Type GetDefaultValue() { return T(ForceInit); } }