#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) /** * Default constructs a range of items in memory. * * @param Address - The address of the first memory location to construct at. * @param Count - The number of elements to construct. */ template <CDefaultConstructible ElementType> FORCEINLINE void DefaultConstruct(void* Address, size_t Count = 1) { if constexpr (!CTriviallyDefaultConstructible<ElementType>) { while (Count) { new (Address) ElementType; ++reinterpret_cast<ElementType*&>(Address); --Count; } } } /** * Constructs a range of items into memory from a set of arguments. The arguments come from an another array. * * @param Destination - The memory location to start copying into. * @param Source - A pointer to the first argument to pass to the constructor. * @param Count - The number of elements to copy. */ template <typename DestinationElementType, typename SourceElementType = DestinationElementType> requires (CConstructibleFrom<DestinationElementType, const SourceElementType&>) FORCEINLINE void Construct(void* Destination, const SourceElementType* Source, size_t Count = 1) { if constexpr (CTriviallyConstructibleFrom<DestinationElementType, const SourceElementType> && sizeof(DestinationElementType) == sizeof(SourceElementType)) { Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count); } else { while (Count) { new (Destination) DestinationElementType(*Source); ++reinterpret_cast<DestinationElementType*&>(Destination); ++Source; --Count; } } } /** * Copy constructs a range of items into memory. * * @param Destination - The memory location to start copying into. * @param Source - A pointer to the first item to copy from. * @param Count - The number of elements to copy. */ template <CCopyConstructible ElementType> FORCEINLINE void CopyConstruct(void* Destination, const ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyCopyConstructible<ElementType>) { Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { new (Destination) ElementType(*Source); ++reinterpret_cast<ElementType*&>(Destination); ++Source; --Count; } } } /** * Move constructs a range of items into memory. * * @param Destination - The memory location to start moving into. * @param Source - A pointer to the first item to move from. * @param Count - The number of elements to move. */ template <CMoveConstructible ElementType> FORCEINLINE void MoveConstruct(void* Destination, ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyMoveConstructible<ElementType>) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { new (Destination) ElementType(MoveTemp(*Source)); ++reinterpret_cast<ElementType*&>(Destination); ++Source; --Count; } } } /** * Copy assigns a range of items. * * @param Destination - The memory location to start assigning to. * @param Source - A pointer to the first item to assign. * @param Count - The number of elements to assign. */ template <CCopyAssignable ElementType> FORCEINLINE void CopyAssign(ElementType* Destination, const ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyCopyAssignable<ElementType>) { Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = *Source; ++Destination; ++Source; --Count; } } } /** * Move assigns a range of items. * * @param Destination - The memory location to start assigning to. * @param Source - A pointer to the first item to assign. * @param Count - The number of elements to assign. */ template <CMoveAssignable ElementType> FORCEINLINE void MoveAssign(ElementType* Destination, ElementType* Source, size_t Count = 1) { if constexpr (CTriviallyMoveAssignable<ElementType>) { Memory::Memmove(Destination, Source, sizeof(ElementType) * Count); } else { while (Count) { *Destination = MoveTemp(*Source); ++Destination; ++Source; --Count; } } } /** * Destructs a range of items in memory. * * @param Elements - A pointer to the first item to destruct. * @param Count - The number of elements to destruct. */ template <CDestructible ElementType> FORCEINLINE void Destruct(ElementType* Element, size_t Count = 1) { if constexpr (!CTriviallyDestructible<ElementType>) { while (Count) { Element->~ElementType(); ++Element; --Count; } } } NAMESPACE_END(Memory) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END