187 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "HAL/Memory.h"
 | 
						|
#include "Templates/TypeTraits.h"
 | 
						|
#include "MemoryOps.h"
 | 
						|
 | 
						|
NS_REDCRAFT_BEGIN
 | 
						|
NS_BEGIN(Memory)
 | 
						|
 | 
						|
NS_PRIVATE_BEGIN
 | 
						|
 | 
						|
template <typename DestinationElementType, typename SourceElementType>
 | 
						|
struct TCanBitwiseRelocate
 | 
						|
{
 | 
						|
	enum
 | 
						|
	{
 | 
						|
		Value =
 | 
						|
		TypeTraits::TOr<
 | 
						|
			TypeTraits::TIsSame<DestinationElementType, SourceElementType>,
 | 
						|
			TypeTraits::TAnd<
 | 
						|
				TypeTraits::TIsBitwiseConstructible<DestinationElementType, SourceElementType>,
 | 
						|
				TypeTraits::TIsTriviallyDestructible<SourceElementType>
 | 
						|
			>
 | 
						|
		>::Value
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
NS_PRIVATE_END
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE void DefaultConstructItems(void* Address, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TIsZeroConstructType<ElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memset(Address, 0, sizeof(ElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		ElementType* Element = (ElementType*)Address;
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			new (Element) ElementType;
 | 
						|
			++Element;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE void DestructItems(ElementType* Element, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (!TypeTraits::TIsTriviallyDestructible<ElementType>::Value)
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			typedef ElementType DestructItemsElementTypeTypedef;
 | 
						|
 | 
						|
			Element->DestructItemsElementTypeTypedef::~DestructItemsElementTypeTypedef();
 | 
						|
			++Element;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename DestinationElementType, typename SourceElementType, typename SizeType>
 | 
						|
FORCEINLINE void ConstructItems(void* Dest, const SourceElementType* Source, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TIsBitwiseConstructible<DestinationElementType, SourceElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memcpy(Dest, Source, sizeof(SourceElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			new (Dest) DestinationElementType(*Source);
 | 
						|
			++(DestinationElementType*&)Dest;
 | 
						|
			++Source;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE void CopyAssignItems(ElementType* Dest, const ElementType* Source, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TIsTriviallyCopyAssignable<ElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memcpy(Dest, Source, sizeof(ElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			*Dest = *Source;
 | 
						|
			++Dest;
 | 
						|
			++Source;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename DestinationElementType, typename SourceElementType, typename SizeType>
 | 
						|
FORCEINLINE void RelocateConstructItems(void* Dest, const SourceElementType* Source, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (NS_PRIVATE::TCanBitwiseRelocate<DestinationElementType, SourceElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memmove(Dest, Source, sizeof(SourceElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			typedef SourceElementType RelocateConstructItemsElementTypeTypedef;
 | 
						|
 | 
						|
			new (Dest) DestinationElementType(*Source);
 | 
						|
			++(DestinationElementType*&)Dest;
 | 
						|
			(Source++)->RelocateConstructItemsElementTypeTypedef::~RelocateConstructItemsElementTypeTypedef();
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE void MoveConstructItems(void* Dest, const ElementType* Source, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TIsTriviallyCopyConstructible<ElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memmove(Dest, Source, sizeof(ElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			new (Dest) ElementType((ElementType&&)*Source);
 | 
						|
			++(ElementType*&)Dest;
 | 
						|
			++Source;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE void MoveAssignItems(ElementType* Dest, const ElementType* Source, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TIsTriviallyCopyAssignable<ElementType>::Value)
 | 
						|
	{
 | 
						|
		Memory::Memmove(Dest, Source, sizeof(ElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			*Dest = (ElementType&&)*Source;
 | 
						|
			++Dest;
 | 
						|
			++Source;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
template<typename ElementType, typename SizeType>
 | 
						|
FORCEINLINE bool CompareItems(const ElementType* A, const ElementType* B, SizeType Count)
 | 
						|
{
 | 
						|
	if constexpr (TypeTraits::TCanBitwiseCompare<ElementType>::Value)
 | 
						|
	{
 | 
						|
		return !Memory::Memcmp(A, B, sizeof(ElementType) * Count);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		while (Count)
 | 
						|
		{
 | 
						|
			if (!(*A == *B))
 | 
						|
			{
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			++A;
 | 
						|
			++B;
 | 
						|
			--Count;
 | 
						|
		}
 | 
						|
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
NS_END(Memory)
 | 
						|
NS_REDCRAFT_END
 |