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