refactor(*): add check and constraint diagnostics for illegal alignment

This commit is contained in:
_Redstone_c_ 2022-04-27 22:50:56 +08:00
parent 897ee4f283
commit 494928aa6b
5 changed files with 18 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#include "Memory/Memory.h" #include "Memory/Memory.h"
#include "Memory/Alignment.h" #include "Memory/Alignment.h"
#include "Miscellaneous/AssertionMacros.h"
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS
#include <corecrt_malloc.h> #include <corecrt_malloc.h>
@ -14,6 +15,8 @@ NAMESPACE_BEGIN(Memory)
void* Malloc(size_t Count, size_t Alignment) 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; const size_t MinimumAlignment = Count >= 16 ? 16 : 8;
Alignment = MinimumAlignment > Alignment ? MinimumAlignment : Alignment; 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) 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; const size_t MinimumAlignment = Count >= 16 ? 16 : 8;
Alignment = MinimumAlignment > Alignment ? MinimumAlignment : Alignment; Alignment = MinimumAlignment > Alignment ? MinimumAlignment : Alignment;

View File

@ -2,6 +2,7 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/TypeTraits.h"
#include "Miscellaneous/AssertionMacros.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
@ -9,27 +10,33 @@ NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Memory) NAMESPACE_BEGIN(Memory)
FORCEINLINE constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); }
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
FORCEINLINE constexpr T Align(T InValue, size_t Alignment) 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<uint64>(Alignment) - 1) & ~(static_cast<uint64>(Alignment) - 1)); return (T)(((uint64)(InValue) + static_cast<uint64>(Alignment) - 1) & ~(static_cast<uint64>(Alignment) - 1));
} }
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
FORCEINLINE constexpr T AlignDown(T InValue, size_t Alignment) 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<uint64>(Alignment) - 1)); return (T)((uint64)(InValue) & ~(static_cast<uint64>(Alignment) - 1));
} }
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
FORCEINLINE constexpr T AlignArbitrary(T InValue, size_t Alignment) 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<uint64>(Alignment) - 1) / static_cast<uint64>(Alignment)) * static_cast<uint64>(Alignment)); return (T)((((uint64)(InValue) + static_cast<uint64>(Alignment) - 1) / static_cast<uint64>(Alignment)) * static_cast<uint64>(Alignment));
} }
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
FORCEINLINE constexpr bool IsAligned(T InValue, size_t Alignment) 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<uint64>(Alignment) - 1)); return !((uint64)(InValue) & (static_cast<uint64>(Alignment) - 1));
} }

View File

@ -31,7 +31,7 @@ private:
}; };
#define RS_CHECK_IMPL(InExpr) assert(InExpr) #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 NAMESPACE_PRIVATE_END

View File

@ -2,6 +2,7 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Memory/Memory.h" #include "Memory/Memory.h"
#include "Memory/Alignment.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "Templates/TypeHash.h" #include "Templates/TypeHash.h"
#include "TypeTraits/TypeTraits.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_SIZE = 48;
inline constexpr size_t ANY_DEFAULT_INLINE_ALIGNMENT = 16; inline constexpr size_t ANY_DEFAULT_INLINE_ALIGNMENT = 16;
template <size_t InlineSize, size_t InlineAlignment = ANY_DEFAULT_INLINE_ALIGNMENT> template <size_t InlineSize, size_t InlineAlignment = ANY_DEFAULT_INLINE_ALIGNMENT> requires (Memory::IsValidAlignment(InlineAlignment))
struct TAny struct TAny
{ {
template <typename T> template <typename T>

View File

@ -6,6 +6,7 @@
#include "Templates/Any.h" #include "Templates/Any.h"
#include "Templates/Tuple.h" #include "Templates/Tuple.h"
#include "Templates/Invoke.h" #include "Templates/Invoke.h"
#include "Memory/Alignment.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "Templates/TypeHash.h" #include "Templates/TypeHash.h"
#include "Templates/Container.h" #include "Templates/Container.h"
@ -39,7 +40,7 @@ enum class EFunctionSpecifiers
ConstRValue, ConstRValue,
}; };
template <typename F, size_t InlineSize, size_t InlineAlignment, EFunctionSpecifiers Specifiers, EFunctionType FunctionType> template <typename F, size_t InlineSize, size_t InlineAlignment, EFunctionSpecifiers Specifiers, EFunctionType FunctionType> requires (Memory::IsValidAlignment(InlineAlignment))
struct TFunctionImpl; struct TFunctionImpl;
template <typename T> struct TIsTFunctionImpl : FFalse { }; template <typename T> 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; inline constexpr size_t FUNCTION_DEFAULT_INLINE_ALIGNMENT = 16;
template <typename F> template <typename F>
using TFunctionRef = typename NAMESPACE_PRIVATE::TFunctionSelect<F, INDEX_NONE, INDEX_NONE, NAMESPACE_PRIVATE::EFunctionType::Reference>::Type; using TFunctionRef = typename NAMESPACE_PRIVATE::TFunctionSelect<F, 0, 0, NAMESPACE_PRIVATE::EFunctionType::Reference>::Type;
template <typename F, size_t InlineSize = FUNCTION_DEFAULT_INLINE_SIZE, size_t InlineAlignment = FUNCTION_DEFAULT_INLINE_ALIGNMENT> template <typename F, size_t InlineSize = FUNCTION_DEFAULT_INLINE_SIZE, size_t InlineAlignment = FUNCTION_DEFAULT_INLINE_ALIGNMENT>
using TFunction = typename NAMESPACE_PRIVATE::TFunctionSelect<F, InlineSize, InlineAlignment, NAMESPACE_PRIVATE::EFunctionType::Object>::Type; using TFunction = typename NAMESPACE_PRIVATE::TFunctionSelect<F, InlineSize, InlineAlignment, NAMESPACE_PRIVATE::EFunctionType::Object>::Type;