fix(memory): support for creating TUniqueRef object from MakeUnique()
This commit is contained in:
parent
fb0d1e978d
commit
c4e0528d93
@ -274,7 +274,7 @@ NAMESPACE_UNNAMED_END
|
|||||||
void TestUniquePointer()
|
void TestUniquePointer()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
TUniqueRef<int32> Temp(new int32);
|
TUniqueRef<int32> Temp = MakeUnique<int32>();
|
||||||
*Temp = 15;
|
*Temp = 15;
|
||||||
always_check(*Temp.Get() = 15);
|
always_check(*Temp.Get() = 15);
|
||||||
}
|
}
|
||||||
@ -327,7 +327,7 @@ void TestUniquePointer()
|
|||||||
always_check(FDeleter::Num == 4);
|
always_check(FDeleter::Num == 4);
|
||||||
|
|
||||||
{
|
{
|
||||||
TUniqueRef<int32[]> Temp(new int32[4]);
|
TUniqueRef<int32[]> Temp = MakeUnique<int32[]>(4);
|
||||||
Temp[0] = 15;
|
Temp[0] = 15;
|
||||||
always_check(Temp.Get()[0] = 15);
|
always_check(Temp.Get()[0] = 15);
|
||||||
}
|
}
|
||||||
|
@ -435,22 +435,6 @@ public:
|
|||||||
: Pointer(InPtr), Controller(InController)
|
: Pointer(InPtr), Controller(InController)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename U> requires (CArray<T> == CArray<U> && ((!CArray<U> && CConvertibleTo<T(*)[], U(*)[]>)
|
|
||||||
|| (CArray<U> && CConvertibleTo<TRemoveExtent<T>(*)[], TRemoveExtent<U>(*)[]>)))
|
|
||||||
NODISCARD FORCEINLINE operator TSharedRef<U>() &&
|
|
||||||
{
|
|
||||||
check_code({ return TSharedRef<U>(Pointer, Exchange(Controller, nullptr)); });
|
|
||||||
return TSharedRef<U>(Pointer, Controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U> requires (CArray<T> == CArray<U> && ((!CArray<U> && CConvertibleTo<T(*)[], U(*)[]>)
|
|
||||||
|| (CArray<U> && CConvertibleTo<TRemoveExtent<T>(*)[], TRemoveExtent<U>(*)[]>)))
|
|
||||||
NODISCARD FORCEINLINE operator TSharedPtr<U>() &&
|
|
||||||
{
|
|
||||||
check_code({ return TSharedPtr<U>(Pointer, Exchange(Controller, nullptr)); });
|
|
||||||
return TSharedPtr<U>(Pointer, Controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
# if DO_CHECK
|
# if DO_CHECK
|
||||||
|
|
||||||
FORCEINLINE ~TSharedProxy() { checkf(Controller == nullptr, TEXT("The return value from MakeShared() is incorrectly ignored.")); }
|
FORCEINLINE ~TSharedProxy() { checkf(Controller == nullptr, TEXT("The return value from MakeShared() is incorrectly ignored.")); }
|
||||||
@ -462,6 +446,10 @@ private:
|
|||||||
TRemoveExtent<T>* Pointer;
|
TRemoveExtent<T>* Pointer;
|
||||||
FSharedController* Controller;
|
FSharedController* Controller;
|
||||||
|
|
||||||
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class NAMESPACE_REDCRAFT::TSharedRef;
|
||||||
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class NAMESPACE_REDCRAFT::TSharedPtr;
|
||||||
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class NAMESPACE_REDCRAFT::TWeakPtr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FSharedPtrConstructor { explicit FSharedPtrConstructor() = default; };
|
struct FSharedPtrConstructor { explicit FSharedPtrConstructor() = default; };
|
||||||
@ -714,6 +702,15 @@ public:
|
|||||||
Swap(A.Controller, B.Controller);
|
Swap(A.Controller, B.Controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::TSharedProxy<U>&& InValue)
|
||||||
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Controller = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
T* Pointer;
|
T* Pointer;
|
||||||
@ -755,8 +752,6 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
|
||||||
|
|
||||||
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -932,6 +927,15 @@ public:
|
|||||||
Swap(A.Controller, B.Controller);
|
Swap(A.Controller, B.Controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
|
FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::TSharedProxy<U>&& InValue)
|
||||||
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Controller = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
T* Pointer;
|
T* Pointer;
|
||||||
@ -958,8 +962,6 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
|
||||||
|
|
||||||
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1185,6 +1187,15 @@ public:
|
|||||||
Swap(A.Controller, B.Controller);
|
Swap(A.Controller, B.Controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U>)
|
||||||
|
FORCEINLINE TSharedPtr(NAMESPACE_PRIVATE::TSharedProxy<U>&& InValue)
|
||||||
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Controller = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
T* Pointer;
|
T* Pointer;
|
||||||
@ -1224,8 +1235,6 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
|
||||||
|
|
||||||
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1453,6 +1462,15 @@ public:
|
|||||||
Swap(A.Controller, B.Controller);
|
Swap(A.Controller, B.Controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>)
|
||||||
|
FORCEINLINE TSharedPtr(NAMESPACE_PRIVATE::TSharedProxy<U>&& InValue)
|
||||||
|
: Pointer(InValue.Pointer), Controller(InValue.Controller)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Controller = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
T* Pointer;
|
T* Pointer;
|
||||||
@ -1477,8 +1495,6 @@ private:
|
|||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TSharedPtr;
|
||||||
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
template <typename U> requires (CObject<U> && !CBoundedArray<U>) friend class TWeakPtr;
|
||||||
|
|
||||||
template <typename U> friend class NAMESPACE_PRIVATE::TSharedProxy;
|
|
||||||
|
|
||||||
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
friend struct NAMESPACE_PRIVATE::FSharedHelper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -145,6 +145,34 @@ concept CTUniqueRef = NAMESPACE_PRIVATE::TIsTUniqueRef<TRemoveCV<T>>::Value;
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
concept CTUniquePtr = NAMESPACE_PRIVATE::TIsTUniquePtr<TRemoveCV<T>>::Value;
|
concept CTUniquePtr = NAMESPACE_PRIVATE::TIsTUniquePtr<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TUniqueProxy : private FSingleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORCEINLINE TUniqueProxy(TRemoveExtent<T>* InPtr)
|
||||||
|
: Pointer(InPtr)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
# if DO_CHECK
|
||||||
|
|
||||||
|
FORCEINLINE ~TUniqueProxy() { checkf(Pointer == nullptr, TEXT("The return value from MakeUnique() is incorrectly ignored.")); }
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
TRemoveExtent<T>* Pointer;
|
||||||
|
|
||||||
|
template <typename U, CInvocable<TRemoveExtent<U>*> E> requires (CObject<U> && !CBoundedArray<U> && (CDestructible<E> || CLValueReference<E>)) friend class NAMESPACE_REDCRAFT::TUniqueRef;
|
||||||
|
template <typename U, CInvocable<TRemoveExtent<U>*> E> requires (CObject<U> && !CBoundedArray<U> && (CDestructible<E> || CLValueReference<E>)) friend class NAMESPACE_REDCRAFT::TUniquePtr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
/** This is essentially a reference version of TUniquePtr. */
|
/** This is essentially a reference version of TUniquePtr. */
|
||||||
template <typename T, CInvocable<TRemoveExtent<T>*> E> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
template <typename T, CInvocable<TRemoveExtent<T>*> E> requires (CObject<T> && !CBoundedArray<T> && (CDestructible<E> || CLValueReference<E>))
|
||||||
class TUniqueRef final : private FSingleton
|
class TUniqueRef final : private FSingleton
|
||||||
@ -256,6 +284,15 @@ public:
|
|||||||
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U> && CSameAs<E, TDefaultDelete<T>>)
|
||||||
|
FORCEINLINE TUniqueRef(NAMESPACE_PRIVATE::TUniqueProxy<U>&& InValue)
|
||||||
|
: Storage(InValue.Pointer)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Pointer = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
||||||
@ -381,6 +418,15 @@ public:
|
|||||||
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && CSameAs<E, TDefaultDelete<T[]>>)
|
||||||
|
FORCEINLINE TUniqueRef(NAMESPACE_PRIVATE::TUniqueProxy<U>&& InValue)
|
||||||
|
: Storage(InValue.Pointer)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Pointer = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
||||||
@ -512,6 +558,15 @@ public:
|
|||||||
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<U*, T*> && !CArray<U> && CSameAs<E, TDefaultDelete<T>>)
|
||||||
|
FORCEINLINE TUniquePtr(NAMESPACE_PRIVATE::TUniqueProxy<U>&& InValue)
|
||||||
|
: Storage(InValue.Pointer)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Pointer = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
||||||
@ -654,6 +709,15 @@ public:
|
|||||||
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
Swap(A.Storage.GetDeleter(), B.Storage.GetDeleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename U> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U> && CSameAs<E, TDefaultDelete<T[]>>)
|
||||||
|
FORCEINLINE TUniquePtr(NAMESPACE_PRIVATE::TUniqueProxy<U>&& InValue)
|
||||||
|
: Storage(InValue.Pointer)
|
||||||
|
{
|
||||||
|
check_code({ InValue.Pointer = nullptr; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
NAMESPACE_PRIVATE::TUniqueStorage<T, E> Storage;
|
||||||
@ -665,21 +729,21 @@ private:
|
|||||||
|
|
||||||
/** Constructs an object of type T and wraps it in a TUniquePtr. */
|
/** 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>)
|
template <typename T, typename... Ts> requires (CObject<T> && !CArray<T> && CConstructibleFrom<T, Ts...> && CDestructible<T>)
|
||||||
NODISCARD FORCEINLINE constexpr TUniquePtr<T> MakeUnique(Ts&&... Args)
|
NODISCARD FORCEINLINE constexpr NAMESPACE_PRIVATE::TUniqueProxy<T> MakeUnique(Ts&&... Args)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(Ts) == 0)
|
if constexpr (sizeof...(Ts) == 0)
|
||||||
{
|
{
|
||||||
return TUniquePtr<T>(new T);
|
return NAMESPACE_PRIVATE::TUniqueProxy<T>(new T);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TUniquePtr<T>(new T(Forward<Ts>(Args)...));
|
return NAMESPACE_PRIVATE::TUniqueProxy<T>(new T(Forward<Ts>(Args)...));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs an array of type T and wraps it in a TUniquePtr. */
|
/** Constructs an array of type T and wraps it in a TUniquePtr. */
|
||||||
template <typename T> requires (CUnboundedArray<T> && CDefaultConstructible<TRemoveExtent<T>> && CDestructible<TRemoveExtent<T>>)
|
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 NAMESPACE_PRIVATE::TUniqueProxy<T> MakeUnique(size_t N) { return NAMESPACE_PRIVATE::TUniqueProxy<T>(new TRemoveExtent<T>[N]); }
|
||||||
|
|
||||||
/** Construction of arrays of known bound is disallowed. */
|
/** Construction of arrays of known bound is disallowed. */
|
||||||
template <typename T, typename... Ts> requires (CBoundedArray<T>)
|
template <typename T, typename... Ts> requires (CBoundedArray<T>)
|
||||||
|
Loading…
Reference in New Issue
Block a user