Compare commits
4 Commits
4ab63da977
...
fb0d1e978d
Author | SHA1 | Date | |
---|---|---|---|
fb0d1e978d | |||
0c54bbe2ac | |||
05d59ed323 | |||
151c90d371 |
@ -291,9 +291,9 @@ void TestUniquePointer()
|
||||
TUniqueRef<FCounter, FDeleter> TempB(PtrB);
|
||||
TUniqueRef<FCounter, FDeleter> TempC(PtrC, FDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -344,9 +344,9 @@ void TestUniquePointer()
|
||||
TUniqueRef<FCounter[], FArrayDeleter> TempB(PtrB);
|
||||
TUniqueRef<FCounter[], FArrayDeleter> TempC(PtrC, FArrayDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -379,12 +379,6 @@ void TestUniquePointer()
|
||||
always_check( FCounter::Num == 0);
|
||||
always_check(FArrayDeleter::Num == 4);
|
||||
|
||||
{
|
||||
TUniquePtr<int32> Temp = MakeUnique<int32>(NoInit);
|
||||
*Temp = 15;
|
||||
always_check(*Temp.Get() = 15);
|
||||
}
|
||||
|
||||
{
|
||||
TUniquePtr<int32> Temp = MakeUnique<int32>();
|
||||
*Temp = 15;
|
||||
@ -403,9 +397,9 @@ void TestUniquePointer()
|
||||
TUniquePtr<FCounter, FDeleter> TempB(PtrB);
|
||||
TUniquePtr<FCounter, FDeleter> TempC(PtrC, FDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -450,12 +444,6 @@ void TestUniquePointer()
|
||||
always_check(FCounter::Num == 0);
|
||||
always_check(FDeleter::Num == 4);
|
||||
|
||||
{
|
||||
TUniquePtr<int32[]> Temp = MakeUnique<int32[]>(4, NoInit);
|
||||
Temp[0] = 15;
|
||||
always_check(Temp.Get()[0] = 15);
|
||||
}
|
||||
|
||||
{
|
||||
TUniquePtr<int32[]> Temp = MakeUnique<int32[]>(4);
|
||||
Temp[0] = 15;
|
||||
@ -474,9 +462,9 @@ void TestUniquePointer()
|
||||
TUniquePtr<FCounter[], FArrayDeleter> TempB(PtrB);
|
||||
TUniquePtr<FCounter[], FArrayDeleter> TempC(PtrC, FArrayDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -552,9 +540,9 @@ void TestSharedPointer()
|
||||
TSharedRef<FCounter> TempB(PtrB, FDeleter());
|
||||
TSharedRef<FCounter> TempC(PtrC, FDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -581,12 +569,6 @@ void TestSharedPointer()
|
||||
always_check(FCounter::Num == 0);
|
||||
always_check(FDeleter::Num == 4);
|
||||
|
||||
{
|
||||
TSharedRef<int32[]> Temp = MakeShared<int32[]>(4, NoInit);
|
||||
Temp[0] = 15;
|
||||
always_check(Temp.Get()[0] = 15);
|
||||
}
|
||||
|
||||
{
|
||||
TSharedRef<int32[]> Temp = MakeShared<int32[]>(4);
|
||||
Temp[0] = 15;
|
||||
@ -605,9 +587,9 @@ void TestSharedPointer()
|
||||
TSharedRef<FCounter[]> TempB(PtrB, FArrayDeleter());
|
||||
TSharedRef<FCounter[]> TempC(PtrC, FArrayDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -646,9 +628,9 @@ void TestSharedPointer()
|
||||
TSharedPtr<FCounter> TempB(PtrB, FDeleter());
|
||||
TSharedPtr<FCounter> TempC(PtrC, FDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
@ -684,12 +666,6 @@ void TestSharedPointer()
|
||||
always_check(FCounter::Num == 0);
|
||||
always_check(FDeleter::Num == 5);
|
||||
|
||||
{
|
||||
TSharedPtr<int32[]> Temp = MakeShared<int32[]>(4, NoInit);
|
||||
Temp[0] = 15;
|
||||
always_check(Temp.Get()[0] = 15);
|
||||
}
|
||||
|
||||
{
|
||||
TSharedPtr<int32[]> Temp = MakeShared<int32[]>(4);
|
||||
Temp[0] = 15;
|
||||
@ -708,9 +684,9 @@ void TestSharedPointer()
|
||||
TSharedPtr<FCounter[]> TempB(PtrB, FArrayDeleter());
|
||||
TSharedPtr<FCounter[]> TempC(PtrC, FArrayDeleter());
|
||||
|
||||
always_check(TempA == PtrA);
|
||||
always_check(TempA != nullptr);
|
||||
always_check(TempC != TempB);
|
||||
always_check((TempA <=> PtrA) == strong_ordering::equal);
|
||||
always_check((TempA <=> nullptr) == strong_ordering::greater);
|
||||
always_check((TempC <=> TempB) != strong_ordering::equal);
|
||||
|
||||
int32 TempNum;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Memory/Allocator.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
@ -9,8 +10,6 @@
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Memory/ObserverPointer.h"
|
||||
#include "Memory/DefaultAllocator.h"
|
||||
#include "Memory/AllocatorInterface.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
@ -198,6 +197,9 @@ public:
|
||||
using Iterator = NAMESPACE_PRIVATE::TArrayIterator<TArray, ElementType>;
|
||||
using ConstIterator = NAMESPACE_PRIVATE::TArrayIterator<TArray, const ElementType>;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
|
||||
static_assert(CContiguousIterator< Iterator>);
|
||||
static_assert(CContiguousIterator<ConstIterator>);
|
||||
|
||||
@ -1124,6 +1126,12 @@ public:
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator Begin() const { return ConstIterator(this, Storage.GetPointer()); }
|
||||
NODISCARD FORCEINLINE constexpr Iterator End() { return Iterator(this, Storage.GetPointer() + Num()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator End() const { return ConstIterator(this, Storage.GetPointer() + Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator RBegin() { return MakeReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator RBegin() const { return MakeReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator REnd() { return MakeReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator REnd() const { return MakeReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() const { return Storage.GetNum(); }
|
||||
|
@ -128,6 +128,83 @@ concept CContiguousIterator = CRandomAccessIterator<I> && CLValueReference<TIter
|
||||
|
||||
static_assert(CContiguousIterator<int32*>);
|
||||
|
||||
/** A iterator adaptor for reverse-order traversal. */
|
||||
template <CBidirectionalIterator I>
|
||||
class TReverseIterator
|
||||
{
|
||||
public:
|
||||
|
||||
using IteratorType = I;
|
||||
|
||||
using ElementType = TIteratorElementType<I>;
|
||||
|
||||
FORCEINLINE constexpr TReverseIterator() = default;
|
||||
|
||||
FORCEINLINE constexpr TReverseIterator(const TReverseIterator&) = default;
|
||||
FORCEINLINE constexpr TReverseIterator(TReverseIterator&&) = default;
|
||||
FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator&) = default;
|
||||
FORCEINLINE constexpr TReverseIterator& operator=(TReverseIterator&&) = default;
|
||||
|
||||
FORCEINLINE constexpr explicit TReverseIterator(IteratorType InValue) : Current(InValue) { }
|
||||
|
||||
template <typename J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<const J&, IteratorType>)
|
||||
FORCEINLINE constexpr TReverseIterator(const TReverseIterator<J>& InValue) : Current(InValue.Current) { }
|
||||
|
||||
template <typename J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<const J&, IteratorType> && CAssignableFrom<IteratorType&, const J&>)
|
||||
FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator<J>& InValue) { Current = InValue.Current; return *this; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator& RHS) { return LHS.Current == RHS.Current; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult<IteratorType> operator<=>(const TReverseIterator& LHS, const TReverseIterator& RHS) requires (CRandomAccessIterator<IteratorType>) { return RHS.Current <=> LHS.Current; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr ElementType& operator*() const { IteratorType Temp = Current; return *--Temp; }
|
||||
NODISCARD FORCEINLINE constexpr ElementType* operator->() const { return AddressOf(operator*()); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr ElementType& operator[](ptrdiff Index) const requires (CRandomAccessIterator<IteratorType>) { return Current[-Index - 1]; }
|
||||
|
||||
FORCEINLINE constexpr TReverseIterator& operator++() { --Current; return *this; }
|
||||
FORCEINLINE constexpr TReverseIterator& operator--() { ++Current; return *this; }
|
||||
|
||||
FORCEINLINE constexpr TReverseIterator operator++(int) { TReverseIterator Temp = *this; --Current; return Temp; }
|
||||
FORCEINLINE constexpr TReverseIterator operator--(int) { TReverseIterator Temp = *this; ++Current; return Temp; }
|
||||
|
||||
FORCEINLINE constexpr TReverseIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current -= Offset; return *this; }
|
||||
FORCEINLINE constexpr TReverseIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current += Offset; return *this; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(TReverseIterator Iter, ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { TReverseIterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset, TReverseIterator Iter) requires (CRandomAccessIterator<IteratorType>) { TReverseIterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<IteratorType>) { return TReverseIterator(Current + Offset); }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) requires (CRandomAccessIterator<IteratorType>) { return TReverseIterator(RHS.Current - LHS.Current); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr const IteratorType GetBase() const { return Current; }
|
||||
|
||||
private:
|
||||
|
||||
IteratorType Current;
|
||||
|
||||
template <CBidirectionalIterator J>
|
||||
friend class TReverseIterator;
|
||||
|
||||
};
|
||||
|
||||
static_assert(CRandomAccessIterator<TReverseIterator<int32*>>);
|
||||
|
||||
template <typename I>
|
||||
TReverseIterator(I) -> TReverseIterator<I>;
|
||||
|
||||
/** Creates a TReverseIterator of type inferred from the argument. */
|
||||
template <typename I>
|
||||
constexpr TReverseIterator<I> MakeReverseIterator(I Iter)
|
||||
{
|
||||
return TReverseIterator<I>(Iter);
|
||||
}
|
||||
|
||||
template <typename I, typename J> requires (!CSizedSentinelFor<I, J>)
|
||||
inline constexpr bool bDisableSizedSentinelFor<TReverseIterator<I>, TReverseIterator<J>> = true;
|
||||
|
||||
NAMESPACE_BEGIN(Iteration)
|
||||
|
||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||
@ -195,9 +272,9 @@ template <typename T, size_t N> FORCEINLINE constexpr T* Begin( T(&&
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* Begin(const T(& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* Begin(const T(&& Container)[N]) { return Container; }
|
||||
|
||||
/** Overloads the Begin algorithm for T::begin(). */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.begin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) Begin(T&& Container)
|
||||
/** Overloads the Begin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) Begin(initializer_list<T> Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
@ -215,13 +292,53 @@ template <typename T, size_t N> FORCEINLINE constexpr T* End( T(&& Co
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* End(const T(& Container)[N]) { return Container + N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* End(const T(&& Container)[N]) { return Container + N; }
|
||||
|
||||
/** Overloads the End algorithm for T::end(). */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.end() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) End(T&& Container)
|
||||
/** Overloads the End algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) End(initializer_list<T> Container)
|
||||
{
|
||||
return Container.end();
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the beginning of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.RBegin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) RBegin(T&& Container)
|
||||
{
|
||||
return Container.RBegin();
|
||||
}
|
||||
|
||||
/** Overloads the RBegin algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin( T(& Container)[N]) { return MakeReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin( T(&& Container)[N]) { return MakeReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin(const T(& Container)[N]) { return MakeReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin(const T(&& Container)[N]) { return MakeReverseIterator(End(Container)); }
|
||||
|
||||
/** Overloads the RBegin algorithm for T::rbegin(). */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) RBegin(initializer_list<T> Container)
|
||||
{
|
||||
return MakeReverseIterator(Container.end());
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the end of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.REnd() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) REnd(T&& Container)
|
||||
{
|
||||
return Container.REnd();
|
||||
}
|
||||
|
||||
/** Overloads the REnd algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd( T(& Container)[N]) { return MakeReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd( T(&& Container)[N]) { return MakeReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd(const T(& Container)[N]) { return MakeReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd(const T(&& Container)[N]) { return MakeReverseIterator(Begin(Container)); }
|
||||
|
||||
/** Overloads the REnd algorithm for T::end(). */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) REnd(initializer_list<T> Container)
|
||||
{
|
||||
return MakeReverseIterator(Container.begin());
|
||||
}
|
||||
|
||||
NAMESPACE_END(Iteration)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
|
@ -53,6 +53,71 @@ struct FAllocatorInterface
|
||||
};
|
||||
};
|
||||
|
||||
/** This is heap allocator that calls Memory::Malloc() directly for memory allocation. */
|
||||
struct FHeapAllocator : public FAllocatorInterface
|
||||
{
|
||||
template <CObject T>
|
||||
struct ForElementType : public FAllocatorInterface::ForElementType<T>
|
||||
{
|
||||
NODISCARD FORCEINLINE T* Allocate(size_t InNum)
|
||||
{
|
||||
return InNum != 0 ? static_cast<T*>(Memory::Malloc(Memory::QuantizeSize(InNum * sizeof(T)), alignof(T))) : nullptr;
|
||||
}
|
||||
|
||||
FORCEINLINE void Deallocate(T* InPtr)
|
||||
{
|
||||
Memory::Free(InPtr);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackGrow(size_t Num, size_t NumAllocated) const
|
||||
{
|
||||
const size_t FirstGrow = 4;
|
||||
const size_t ConstantGrow = 16;
|
||||
|
||||
size_t Result;
|
||||
|
||||
check(Num > NumAllocated);
|
||||
|
||||
Result = (NumAllocated != 0) ? (Num + 3 * Num / 8 + ConstantGrow) : (Num > FirstGrow ? Num : FirstGrow);
|
||||
|
||||
Result = Memory::QuantizeSize(Result * sizeof(T), alignof(T)) / sizeof(T);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackShrink(size_t Num, size_t NumAllocated) const
|
||||
{
|
||||
size_t Result;
|
||||
|
||||
check(Num < NumAllocated);
|
||||
|
||||
const bool bTooManySlackBytes = (NumAllocated - Num) * sizeof(T) >= 16 * 1024;
|
||||
const bool bTooManySlackElements = 3 * Num < 2 * NumAllocated;
|
||||
|
||||
const bool bNeedToShrink = (bTooManySlackBytes || bTooManySlackElements) && (NumAllocated - Num > 64 || Num == 0);
|
||||
|
||||
if (bNeedToShrink)
|
||||
{
|
||||
Result = Num != 0 ? Memory::QuantizeSize(Num * sizeof(T), alignof(T)) / sizeof(T) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = NumAllocated;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackReserve(size_t Num) const
|
||||
{
|
||||
return Num != 0 ? Memory::QuantizeSize(Num * sizeof(T), alignof(T)) / sizeof(T) : 0;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
using FDefaultAllocator = FHeapAllocator;
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Memory/Memory.h"
|
||||
#include "Memory/HeapAllocator.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
using FDefaultAllocator = FHeapAllocator;
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -1,76 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Memory/Memory.h"
|
||||
#include "Memory/AllocatorInterface.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
/** This is heap allocator that calls Memory::Malloc() directly for memory allocation. */
|
||||
struct FHeapAllocator : public FAllocatorInterface
|
||||
{
|
||||
template <CObject T>
|
||||
struct ForElementType : public FAllocatorInterface::ForElementType<T>
|
||||
{
|
||||
NODISCARD FORCEINLINE T* Allocate(size_t InNum)
|
||||
{
|
||||
return InNum != 0 ? static_cast<T*>(Memory::Malloc(Memory::QuantizeSize(InNum * sizeof(T)), alignof(T))) : nullptr;
|
||||
}
|
||||
|
||||
FORCEINLINE void Deallocate(T* InPtr)
|
||||
{
|
||||
Memory::Free(InPtr);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackGrow(size_t Num, size_t NumAllocated) const
|
||||
{
|
||||
const size_t FirstGrow = 4;
|
||||
const size_t ConstantGrow = 16;
|
||||
|
||||
size_t Result;
|
||||
|
||||
check(Num > NumAllocated);
|
||||
|
||||
Result = (NumAllocated != 0) ? (Num + 3 * Num / 8 + ConstantGrow) : (Num > FirstGrow ? Num : FirstGrow);
|
||||
|
||||
Result = Memory::QuantizeSize(Result * sizeof(T), alignof(T)) / sizeof(T);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackShrink(size_t Num, size_t NumAllocated) const
|
||||
{
|
||||
size_t Result;
|
||||
|
||||
check(Num < NumAllocated);
|
||||
|
||||
const bool bTooManySlackBytes = (NumAllocated - Num) * sizeof(T) >= 16 * 1024;
|
||||
const bool bTooManySlackElements = 3 * Num < 2 * NumAllocated;
|
||||
|
||||
const bool bNeedToShrink = (bTooManySlackBytes || bTooManySlackElements) && (NumAllocated - Num > 64 || Num == 0);
|
||||
|
||||
if (bNeedToShrink)
|
||||
{
|
||||
Result = Num != 0 ? Memory::QuantizeSize(Num * sizeof(T), alignof(T)) / sizeof(T) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = NumAllocated;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr size_t CalculateSlackReserve(size_t Num) const
|
||||
{
|
||||
return Num != 0 ? Memory::QuantizeSize(Num * sizeof(T), alignof(T)) / sizeof(T) : 0;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -241,10 +241,18 @@ class TSharedControllerWithObject final : public FSharedController
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE explicit TSharedControllerWithObject(FNoInit) requires (!CConstructibleFrom<T, FNoInit>) { new (&Storage) T; }
|
||||
|
||||
template <typename... Ts> requires (CConstructibleFrom<T, Ts...>)
|
||||
FORCEINLINE explicit TSharedControllerWithObject(Ts&&... Args) { new (&Storage) T(Forward<Ts>(Args)...); }
|
||||
template <typename... Ts>
|
||||
FORCEINLINE explicit TSharedControllerWithObject(Ts&&... Args)
|
||||
{
|
||||
if constexpr (sizeof...(Ts) == 0)
|
||||
{
|
||||
new (&Storage) T;
|
||||
}
|
||||
else
|
||||
{
|
||||
new (&Storage) T(Forward<Ts>(Args)...);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~TSharedControllerWithObject() = default;
|
||||
|
||||
@ -263,20 +271,11 @@ class TSharedControllerWithArray final : public FSharedController
|
||||
{
|
||||
public:
|
||||
|
||||
static TSharedControllerWithArray* New(size_t N, FNoInit)
|
||||
{
|
||||
void* Buffer = Memory::Malloc(sizeof(TSharedControllerWithArray) + sizeof(T) * (N - 1), alignof(TSharedControllerWithArray));
|
||||
const auto Controller = new (Buffer) TSharedControllerWithArray(N);
|
||||
const T* ElementPtr = new (Controller->GetPointer()) T[N];
|
||||
check(ElementPtr == Controller->GetPointer());
|
||||
return Controller;
|
||||
}
|
||||
|
||||
static TSharedControllerWithArray* New(size_t N)
|
||||
{
|
||||
void* Buffer = Memory::Malloc(sizeof(TSharedControllerWithArray) + sizeof(T) * (N - 1), alignof(TSharedControllerWithArray));
|
||||
const auto Controller = new (Buffer) TSharedControllerWithArray(N);
|
||||
const T* ElementPtr = new (Controller->GetPointer()) T[N]();
|
||||
const T* ElementPtr = new (Controller->GetPointer()) T[N];
|
||||
check(ElementPtr == Controller->GetPointer());
|
||||
return Controller;
|
||||
}
|
||||
@ -637,16 +636,18 @@ public:
|
||||
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||
|
||||
/** Compares the pointer values of two TSharedRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef<U>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TSharedRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef<U>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** TSharedRef cannot be initialized by nullptr. */
|
||||
void Reset(nullptr_t) = delete;
|
||||
@ -674,7 +675,7 @@ public:
|
||||
return ControllerWithDeleter != nullptr ? &ControllerWithDeleter->GetDeleter() : nullptr;
|
||||
}
|
||||
|
||||
/** @return The a reference or pointer to the object owned by *this, i.e. Get(). */
|
||||
/** @return The reference or pointer to the object owned by *this, i.e. Get(). */
|
||||
NODISCARD FORCEINLINE constexpr T& operator*() const { return *Get(); }
|
||||
NODISCARD FORCEINLINE constexpr T* operator->() const { return Get(); }
|
||||
|
||||
@ -853,18 +854,18 @@ public:
|
||||
FORCEINLINE TSharedRef& operator=(TSharedRef<U>&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); }
|
||||
|
||||
/** Compares the pointer values of two TSharedRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef<U>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TSharedRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef<U>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** TSharedRef cannot be initialized by nullptr. */
|
||||
void Reset(nullptr_t) = delete;
|
||||
@ -1095,16 +1096,18 @@ public:
|
||||
FORCEINLINE TSharedPtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||
|
||||
/** Compares the pointer values of two TSharedPtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr<U>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TSharedPtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr<U>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||
FORCEINLINE TSharedRef<T> ToSharedRef() const&
|
||||
@ -1143,7 +1146,7 @@ public:
|
||||
NODISCARD FORCEINLINE constexpr bool IsValid() const { return Get() != nullptr; }
|
||||
NODISCARD FORCEINLINE constexpr explicit operator bool() const { return Get() != nullptr; }
|
||||
|
||||
/** @return The a reference or pointer to the object owned by *this, i.e. Get(). */
|
||||
/** @return The reference or pointer to the object owned by *this, i.e. Get(). */
|
||||
NODISCARD FORCEINLINE constexpr T& operator*() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return *Get(); }
|
||||
NODISCARD FORCEINLINE constexpr T* operator->() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get(); }
|
||||
|
||||
@ -1361,18 +1364,18 @@ public:
|
||||
FORCEINLINE TSharedPtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||
|
||||
/** Compares the pointer values of two TSharedPtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr<U>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TSharedPtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr<U>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */
|
||||
FORCEINLINE TSharedRef<T[]> ToSharedRef() const&
|
||||
@ -1748,14 +1751,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
/** Constructs an object of type T and wraps it in a TSharedRef or TSharedPtr. Without initialization. */
|
||||
template <typename T> requires (CObject<T> && !CArray<T> && !CConstructibleFrom<T, FNoInit> && CDestructible<T>)
|
||||
NODISCARD FORCEINLINE NAMESPACE_PRIVATE::TSharedProxy<T> MakeShared(FNoInit)
|
||||
{
|
||||
const auto Controller = new NAMESPACE_PRIVATE::TSharedControllerWithObject<T>(NoInit);
|
||||
return NAMESPACE_PRIVATE::TSharedProxy<T>(Controller->GetPointer(), Controller);
|
||||
}
|
||||
|
||||
/** Constructs an object of type T and wraps it in a TSharedRef or TSharedPtr. */
|
||||
template <typename T, typename... Ts> requires (CObject<T> && !CArray<T> && CConstructibleFrom<T, Ts...> && CDestructible<T>)
|
||||
NODISCARD FORCEINLINE NAMESPACE_PRIVATE::TSharedProxy<T> MakeShared(Ts&&... Args)
|
||||
@ -1764,14 +1759,6 @@ NODISCARD FORCEINLINE NAMESPACE_PRIVATE::TSharedProxy<T> MakeShared(Ts&&... Args
|
||||
return NAMESPACE_PRIVATE::TSharedProxy<T>(Controller->GetPointer(), Controller);
|
||||
}
|
||||
|
||||
/** Constructs an array of type T and wraps it in a TSharedRef or TSharedPtr. Without initialization. */
|
||||
template <typename T> requires (CUnboundedArray<T> && CDefaultConstructible<TRemoveExtent<T>> && CDestructible<TRemoveExtent<T>>)
|
||||
NODISCARD FORCEINLINE NAMESPACE_PRIVATE::TSharedProxy<T> MakeShared(size_t N, FNoInit)
|
||||
{
|
||||
const auto Controller = NAMESPACE_PRIVATE::TSharedControllerWithArray<TRemoveExtent<T>>::New(N, NoInit);
|
||||
return NAMESPACE_PRIVATE::TSharedProxy<T>(Controller->GetPointer(), Controller);
|
||||
}
|
||||
|
||||
/** Constructs an array of type T and wraps it in a TSharedRef or TSharedPtr. */
|
||||
template <typename T> requires (CUnboundedArray<T> && CDefaultConstructible<TRemoveExtent<T>> && CDestructible<TRemoveExtent<T>>)
|
||||
NODISCARD FORCEINLINE NAMESPACE_PRIVATE::TSharedProxy<T> MakeShared(size_t N)
|
||||
|
@ -177,16 +177,18 @@ public:
|
||||
FORCEINLINE constexpr ~TUniqueRef() { Invoke(GetDeleter(), Get()); }
|
||||
|
||||
/** Compares the pointer values of two TUniqueRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef<U, InE>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TUniqueRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef<U, InE>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** TUniqueRef cannot be reset to nullptr. */
|
||||
void Reset(nullptr_t) = delete;
|
||||
@ -297,18 +299,18 @@ public:
|
||||
FORCEINLINE constexpr ~TUniqueRef() { Invoke(GetDeleter(), Get()); }
|
||||
|
||||
/** Compares the pointer values of two TUniqueRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef<U, InE>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TUniqueRef. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef<U, InE>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** TUniqueRef cannot be reset to nullptr. */
|
||||
void Reset(nullptr_t) = delete;
|
||||
@ -440,16 +442,18 @@ public:
|
||||
FORCEINLINE constexpr TUniquePtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||
|
||||
/** Compares the pointer values of two TUniquePtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr<U, InE>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TUniquePtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr<U, InE>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** Returns a pointer to the managed object and releases the ownership. */
|
||||
NODISCARD FORCEINLINE constexpr T* Release() { return Exchange(Storage.GetPointer(), nullptr); }
|
||||
@ -577,18 +581,18 @@ public:
|
||||
FORCEINLINE constexpr TUniquePtr& operator=(nullptr_t) { Reset(); return *this; }
|
||||
|
||||
/** Compares the pointer values of two TUniquePtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CEqualityComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr<U, InE>& RHS) { return LHS.Get() == RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values of two TUniquePtr. */
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
template <typename U, typename InE> requires (CThreeWayComparable<T*, TRemoveExtent<U>*>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr<U, InE>& RHS) { return LHS.Get() <=> RHS.Get(); }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; }
|
||||
|
||||
/** Compares the pointer values with a raw pointer. */
|
||||
template <typename U = T*> requires (CNullPointer<U> || (CPointer<U> && CConvertibleTo<TRemovePointer<U>(*)[], T(*)[]>))
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; }
|
||||
/** Compares the pointer values with nullptr. */
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast<T*>(nullptr); }
|
||||
|
||||
/** Returns a pointer to the managed array and releases the ownership. */
|
||||
NODISCARD FORCEINLINE constexpr T* Release() { return Exchange(Storage.GetPointer(), nullptr); }
|
||||
@ -659,21 +663,23 @@ private:
|
||||
|
||||
};
|
||||
|
||||
/** Constructs an object of type T and wraps it in a TUniquePtr. Without initialization. */
|
||||
template <typename T> requires (CObject<T> && !CArray<T> && !CConstructibleFrom<T, FNoInit> && CDestructible<T>)
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(FNoInit) { return TUniquePtr<T>(new T); }
|
||||
|
||||
/** Constructs an object of type T and wraps it in a TUniquePtr. */
|
||||
template <typename T, typename... Ts> requires (CObject<T> && !CArray<T> && CConstructibleFrom<T, Ts...> && CDestructible<T>)
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(Ts&&... Args) { return TUniquePtr<T>(new T(Forward<Ts>(Args)...)); }
|
||||
|
||||
/** Constructs an array of type T and wraps it in a TUniquePtr. Without initialization. */
|
||||
template <typename T> requires (CUnboundedArray<T> && CDefaultConstructible<TRemoveExtent<T>> && CDestructible<TRemoveExtent<T>>)
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(size_t N, FNoInit) { return TUniquePtr<T>(new TRemoveExtent<T>[N]); }
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(Ts&&... Args)
|
||||
{
|
||||
if constexpr (sizeof...(Ts) == 0)
|
||||
{
|
||||
return TUniquePtr<T>(new T);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TUniquePtr<T>(new T(Forward<Ts>(Args)...));
|
||||
}
|
||||
}
|
||||
|
||||
/** Constructs an array of type T and wraps it in a TUniquePtr. */
|
||||
template <typename T> requires (CUnboundedArray<T> && CDefaultConstructible<TRemoveExtent<T>> && CDestructible<TRemoveExtent<T>>)
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(size_t N) { return TUniquePtr<T>(new TRemoveExtent<T>[N]()); }
|
||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(size_t N) { return TUniquePtr<T>(new TRemoveExtent<T>[N]); }
|
||||
|
||||
/** Construction of arrays of known bound is disallowed. */
|
||||
template <typename T, typename... Ts> requires (CBoundedArray<T>)
|
||||
|
@ -245,14 +245,14 @@ public:
|
||||
}
|
||||
|
||||
/** Check if the optional value is equivalent to 'InValue'. */
|
||||
template <typename T = OptionalType> requires (!CTOptional<T>&& CWeaklyEqualityComparable<OptionalType, T>)
|
||||
template <typename T = OptionalType> requires (!CTOptional<T> && CWeaklyEqualityComparable<OptionalType, T>)
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||
{
|
||||
return IsValid() ? GetValue() == InValue : false;
|
||||
}
|
||||
|
||||
/** Check that the optional value is in ordered relationship with 'InValue'. */
|
||||
template <typename T = OptionalType> requires (!CTOptional<T>&& CSynthThreeWayComparable<OptionalType, T>)
|
||||
template <typename T = OptionalType> requires (!CTOptional<T> && CSynthThreeWayComparable<OptionalType, T>)
|
||||
NODISCARD FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||
{
|
||||
return IsValid() ? SynthThreeWayCompare(GetValue(), InValue) : partial_ordering::unordered;
|
||||
|
Loading…
Reference in New Issue
Block a user