#pragma once #include "CoreTypes.h" #include "Memory/Memory.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Memory) template requires CDefaultConstructible FORCEINLINE void DefaultConstruct(ElementType* Address, size_t Count = 1) { if constexpr (!CTriviallyDefaultConstructible) { ElementType* Element = Address; while (Count) { new (Element) ElementType; ++Element; --Count; } } } template requires CConstructibleFrom FORCEINLINE void Construct(DestinationElementType* Destination, const SourceElementType* Source, size_t Count = 1) { if constexpr (CTriviallyConstructibleFrom && sizeof(DestinationElementType) == sizeof(SourceElementType)) { Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count); } else { while (Count) { new (Destination) DestinationElementType(*Source); ++(DestinationElementType*&)Destination; ++Source; --Count; } } } template requires CCopyConstructible FORCEINLINE void CopyConstruct(ElementType* Destination, const ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyCopyConstructible) { Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { new (Destination) ElementType(*Source); ++(ElementType*&)Destination; ++Source; --Count; } } } template requires CMoveConstructible FORCEINLINE void MoveConstruct(ElementType* Destination, ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyMoveConstructible) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { new (Destination) ElementType(MoveTemp(*Source)); ++(ElementType*&)Destination; ++Source; --Count; } } } template requires CCopyAssignable FORCEINLINE void CopyAssign(ElementType* Destination, const ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyCopyAssignable) { Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = *Source; ++Destination; ++Source; --Count; } } } template requires CMoveAssignable FORCEINLINE void MoveAssign(ElementType* Destination, ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyMoveAssignable) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = MoveTemp(*Source); ++(ElementType*&)Destination; ++Source; --Count; } } } template requires CDestructible FORCEINLINE void Destruct(ElementType* Element, size_t Count = 1) { if constexpr (!CTriviallyDestructible) { while (Count) { Element->~ElementType(); ++Element; --Count; } } } NAMESPACE_END(Memory) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END