2022-03-19 08:05:47 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "CoreTypes.h"
|
2022-03-19 15:07:04 +00:00
|
|
|
#include "Memory/Memory.h"
|
2022-03-19 08:05:47 +00:00
|
|
|
#include "Templates/Utility.h"
|
|
|
|
#include "TypeTraits/TypeTraits.h"
|
|
|
|
|
|
|
|
NAMESPACE_REDCRAFT_BEGIN
|
|
|
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
|
|
|
NAMESPACE_MODULE_BEGIN(Utility)
|
|
|
|
|
|
|
|
NAMESPACE_BEGIN(Memory)
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CDefaultConstructible ElementType>
|
2022-06-05 14:52:55 +00:00
|
|
|
FORCEINLINE void DefaultConstruct(void* Address, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-21 14:39:22 +00:00
|
|
|
if constexpr (!CTriviallyDefaultConstructible<ElementType>)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
2022-06-05 14:52:55 +00:00
|
|
|
new (Address) ElementType;
|
|
|
|
++reinterpret_cast<ElementType*&>(Address);
|
2022-03-19 08:05:47 +00:00
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-20 15:35:36 +00:00
|
|
|
template <typename DestinationElementType, typename SourceElementType = DestinationElementType>
|
2022-11-16 14:03:54 +00:00
|
|
|
requires (CConstructibleFrom<DestinationElementType, const SourceElementType&>)
|
2022-06-05 14:52:55 +00:00
|
|
|
FORCEINLINE void Construct(void* Destination, const SourceElementType* Source, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-21 14:39:22 +00:00
|
|
|
if constexpr (CTriviallyConstructibleFrom<DestinationElementType, const SourceElementType> && sizeof(DestinationElementType) == sizeof(SourceElementType))
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
|
|
|
new (Destination) DestinationElementType(*Source);
|
2022-06-05 14:52:55 +00:00
|
|
|
++reinterpret_cast<DestinationElementType*&>(Destination);
|
2022-03-19 08:05:47 +00:00
|
|
|
++Source;
|
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CCopyConstructible ElementType>
|
2022-06-05 14:52:55 +00:00
|
|
|
FORCEINLINE void CopyConstruct(void* Destination, const ElementType* Source, size_t Count = 1)
|
2022-04-30 13:33:18 +00:00
|
|
|
{
|
2022-05-16 14:42:17 +00:00
|
|
|
if constexpr (CTriviallyCopyConstructible<ElementType>)
|
2022-04-30 13:33:18 +00:00
|
|
|
{
|
|
|
|
Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
|
|
|
new (Destination) ElementType(*Source);
|
2022-06-05 14:52:55 +00:00
|
|
|
++reinterpret_cast<ElementType*&>(Destination);
|
2022-04-30 13:33:18 +00:00
|
|
|
++Source;
|
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CMoveConstructible ElementType>
|
2022-06-05 14:52:55 +00:00
|
|
|
FORCEINLINE void MoveConstruct(void* Destination, ElementType* Source, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-16 14:42:17 +00:00
|
|
|
if constexpr (CTriviallyMoveConstructible<ElementType>)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
Memory::Memmove(Destination, Source, sizeof(ElementType) * Count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
|
|
|
new (Destination) ElementType(MoveTemp(*Source));
|
2022-06-05 14:52:55 +00:00
|
|
|
++reinterpret_cast<ElementType*&>(Destination);
|
2022-03-19 08:05:47 +00:00
|
|
|
++Source;
|
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CCopyAssignable ElementType>
|
2022-04-30 13:33:18 +00:00
|
|
|
FORCEINLINE void CopyAssign(ElementType* Destination, const ElementType* Source, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-16 14:42:17 +00:00
|
|
|
if constexpr (CTriviallyCopyAssignable<ElementType>)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
Memory::Memcpy(Destination, Source, sizeof(ElementType) * Count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
|
|
|
*Destination = *Source;
|
|
|
|
++Destination;
|
|
|
|
++Source;
|
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CMoveAssignable ElementType>
|
2022-04-30 13:33:18 +00:00
|
|
|
FORCEINLINE void MoveAssign(ElementType* Destination, ElementType* Source, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-21 14:39:22 +00:00
|
|
|
if constexpr (CTriviallyMoveAssignable<ElementType>)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
Memory::Memmove(Destination, Source, sizeof(ElementType) * Count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
|
|
|
*Destination = MoveTemp(*Source);
|
2022-06-05 14:52:55 +00:00
|
|
|
++Destination;
|
2022-03-19 08:05:47 +00:00
|
|
|
++Source;
|
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <CDestructible ElementType>
|
2022-05-21 14:39:22 +00:00
|
|
|
FORCEINLINE void Destruct(ElementType* Element, size_t Count = 1)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
2022-05-21 14:39:22 +00:00
|
|
|
if constexpr (!CTriviallyDestructible<ElementType>)
|
2022-03-19 08:05:47 +00:00
|
|
|
{
|
|
|
|
while (Count)
|
|
|
|
{
|
2022-05-21 14:39:22 +00:00
|
|
|
Element->~ElementType();
|
|
|
|
++Element;
|
2022-03-19 08:05:47 +00:00
|
|
|
--Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NAMESPACE_END(Memory)
|
|
|
|
|
|
|
|
NAMESPACE_MODULE_END(Utility)
|
|
|
|
NAMESPACE_MODULE_END(Redcraft)
|
|
|
|
NAMESPACE_REDCRAFT_END
|