#pragma once #include "CoreTypes.h" #include "Memory/Memory.h" #include "Templates/Utility.h" #include "Concepts/Comparable.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Memory) template requires (TIsDefaultConstructible::Value || TIsZeroConstructible::Value) FORCEINLINE void DefaultConstruct(ElementType* Address, SizeType Count = 1) { if constexpr (TIsZeroConstructible::Value) { Memory::Memset(Address, 0, sizeof(ElementType) * Count); } else { ElementType* Element = (ElementType*)Address; while (Count) { new (Element) ElementType; ++Element; --Count; } } } template requires (TIsConstructible::Value || TIsBitwiseConstructible::Value) FORCEINLINE void Construct(DestinationElementType* Destination, const SourceElementType* Source, SizeType Count = 1) { if constexpr (TIsBitwiseConstructible::Value) { Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count); } else { while (Count) { new (Destination) DestinationElementType(*Source); ++(DestinationElementType*&)Destination; ++Source; --Count; } } } template requires (TIsMoveConstructible::Value) FORCEINLINE void MoveConstruct(ElementType* Destination, ElementType* Source, SizeType Count = 1) { if constexpr (TIsTriviallyMoveConstructible::Value) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { new (Destination) ElementType(MoveTemp(*Source)); ++(ElementType*&)Destination; ++Source; --Count; } } } template requires ((TIsConstructible::Value && TIsDestructible::Value) || TIsBitwiseRelocatable::Value) FORCEINLINE void RelocateConstruct(DestinationElementType* Destination, SourceElementType* Source, SizeType Count = 1) { if constexpr (TIsBitwiseRelocatable::Value) { Memory::Memmove(Destination, Source, sizeof(SourceElementType) * Count); } else { while (Count) { typedef SourceElementType RelocateConstructItemsElementTypeTypedef; new (Destination) DestinationElementType(MoveTemp(*Source)); ++(DestinationElementType*&)Destination; (Source++)->RelocateConstructItemsElementTypeTypedef::~RelocateConstructItemsElementTypeTypedef(); --Count; } } } template requires (TIsDestructible::Value) FORCEINLINE void Destruct(ElementType* Element, SizeType Count = 1) { if constexpr (!TIsTriviallyDestructible::Value) { while (Count) { typedef ElementType DestructItemsElementTypeTypedef; Element->DestructItemsElementTypeTypedef::~DestructItemsElementTypeTypedef(); ++Element; --Count; } } } template requires (TIsCopyAssignable::Value) FORCEINLINE void CopyAssign(ElementType* Destination, const ElementType* Source, SizeType Count = 1) { if constexpr (TIsTriviallyCopyAssignable::Value) { Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = *Source; ++Destination; ++Source; --Count; } } } template requires (TIsMoveAssignable::Value) FORCEINLINE void MoveAssign(ElementType* Destination, ElementType* Source, SizeType Count = 1) { if constexpr (TIsTriviallyCopyConstructible::Value) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = MoveTemp(*Source); ++(ElementType*&)Destination; ++Source; --Count; } } } template requires (CEqualityComparable || TIsBitwiseComparable::Value) FORCEINLINE bool Compare(const ElementType* LHS, const ElementType* RHS, SizeType Count = 1) { if constexpr (TIsBitwiseComparable::Value) { return !Memory::Memcmp(LHS, RHS, sizeof(ElementType) * Count); } else { while (Count) { if (!(*LHS == *RHS)) { return false; } ++LHS; ++RHS; --Count; } return true; } } NAMESPACE_END(Memory) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END