diff --git a/Redcraft.Utility/Source/Private/Memory/Memory.cpp b/Redcraft.Utility/Source/Private/Memory/Memory.cpp index 81e4931..a42e669 100644 --- a/Redcraft.Utility/Source/Private/Memory/Memory.cpp +++ b/Redcraft.Utility/Source/Private/Memory/Memory.cpp @@ -1,6 +1,7 @@ #include "Memory/Memory.h" #include "Memory/Alignment.h" +#include "Miscellaneous/AssertionMacros.h" #if PLATFORM_WINDOWS #include @@ -14,6 +15,8 @@ NAMESPACE_BEGIN(Memory) void* Malloc(size_t Count, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); + const size_t MinimumAlignment = Count >= 16 ? 16 : 8; Alignment = MinimumAlignment > Alignment ? MinimumAlignment : Alignment; @@ -36,6 +39,8 @@ void* Malloc(size_t Count, size_t Alignment) void* Realloc(void* Ptr, size_t Count, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); + const size_t MinimumAlignment = Count >= 16 ? 16 : 8; Alignment = MinimumAlignment > Alignment ? MinimumAlignment : Alignment; diff --git a/Redcraft.Utility/Source/Public/Memory/Alignment.h b/Redcraft.Utility/Source/Public/Memory/Alignment.h index b0eb0b1..d55c72d 100644 --- a/Redcraft.Utility/Source/Public/Memory/Alignment.h +++ b/Redcraft.Utility/Source/Public/Memory/Alignment.h @@ -2,6 +2,7 @@ #include "CoreTypes.h" #include "TypeTraits/TypeTraits.h" +#include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -9,27 +10,33 @@ NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Memory) +FORCEINLINE constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); } + template requires TIsIntegral::Value || TIsPointer::Value FORCEINLINE constexpr T Align(T InValue, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); return (T)(((uint64)(InValue) + static_cast(Alignment) - 1) & ~(static_cast(Alignment) - 1)); } template requires TIsIntegral::Value || TIsPointer::Value FORCEINLINE constexpr T AlignDown(T InValue, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); return (T)((uint64)(InValue) & ~(static_cast(Alignment) - 1)); } template requires TIsIntegral::Value || TIsPointer::Value FORCEINLINE constexpr T AlignArbitrary(T InValue, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); return (T)((((uint64)(InValue) + static_cast(Alignment) - 1) / static_cast(Alignment)) * static_cast(Alignment)); } template requires TIsIntegral::Value || TIsPointer::Value FORCEINLINE constexpr bool IsAligned(T InValue, size_t Alignment) { + checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2.")); return !((uint64)(InValue) & (static_cast(Alignment) - 1)); } diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/AssertionMacros.h b/Redcraft.Utility/Source/Public/Miscellaneous/AssertionMacros.h index 53c224c..5d454f6 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/AssertionMacros.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/AssertionMacros.h @@ -31,7 +31,7 @@ private: }; #define RS_CHECK_IMPL(InExpr) assert(InExpr) -#define RS_CHECK_F_IMPL(InExpr, InFormat, ...) assert(InExpr) +#define RS_CHECK_F_IMPL(InExpr, InFormat, ...) assert((InFormat, InExpr)) NAMESPACE_PRIVATE_END diff --git a/Redcraft.Utility/Source/Public/Templates/Any.h b/Redcraft.Utility/Source/Public/Templates/Any.h index ec8c191..c1c5c55 100644 --- a/Redcraft.Utility/Source/Public/Templates/Any.h +++ b/Redcraft.Utility/Source/Public/Templates/Any.h @@ -2,6 +2,7 @@ #include "CoreTypes.h" #include "Memory/Memory.h" +#include "Memory/Alignment.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "TypeTraits/TypeTraits.h" @@ -161,7 +162,7 @@ NAMESPACE_PRIVATE_END inline constexpr size_t ANY_DEFAULT_INLINE_SIZE = 48; inline constexpr size_t ANY_DEFAULT_INLINE_ALIGNMENT = 16; -template +template requires (Memory::IsValidAlignment(InlineAlignment)) struct TAny { template diff --git a/Redcraft.Utility/Source/Public/Templates/Function.h b/Redcraft.Utility/Source/Public/Templates/Function.h index c0c3e69..7d2ae0f 100644 --- a/Redcraft.Utility/Source/Public/Templates/Function.h +++ b/Redcraft.Utility/Source/Public/Templates/Function.h @@ -6,6 +6,7 @@ #include "Templates/Any.h" #include "Templates/Tuple.h" #include "Templates/Invoke.h" +#include "Memory/Alignment.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "Templates/Container.h" @@ -39,7 +40,7 @@ enum class EFunctionSpecifiers ConstRValue, }; -template +template requires (Memory::IsValidAlignment(InlineAlignment)) struct TFunctionImpl; template struct TIsTFunctionImpl : FFalse { }; @@ -370,7 +371,7 @@ inline constexpr size_t FUNCTION_DEFAULT_INLINE_SIZE = 32; inline constexpr size_t FUNCTION_DEFAULT_INLINE_ALIGNMENT = 16; template -using TFunctionRef = typename NAMESPACE_PRIVATE::TFunctionSelect::Type; +using TFunctionRef = typename NAMESPACE_PRIVATE::TFunctionSelect::Type; template using TFunction = typename NAMESPACE_PRIVATE::TFunctionSelect::Type;