Redcraft/Redcraft.Utility/Source/Public/Memory/MemoryOperator.h

190 lines
4.8 KiB
C++

#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