fix(templates): fix the implementation of the Swap algorithm for arrays

This commit is contained in:
_Redstone_c_ 2023-01-02 22:03:40 +08:00
parent 96ecd33c16
commit 95b492851a
2 changed files with 19 additions and 12 deletions

View File

@ -1,57 +1,76 @@
#pragma once #pragma once
#include "CoreTypes.h" #include "CoreTypes.h"
#include "TypeTraits/Swappable.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
/** @return The pointer or iterator to the container element storage. */
template <typename T> requires (requires(T&& Container) { Container.GetData(); }) template <typename T> requires (requires(T&& Container) { Container.GetData(); })
FORCEINLINE constexpr decltype(auto) GetData(T&& Container) FORCEINLINE constexpr decltype(auto) GetData(T&& Container)
{ {
return Container.GetData(); return Container.GetData();
} }
/** Overloads the GetData algorithm for arrays. */
template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(& Container)[N]) { return Container; }
template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(&& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(&& Container)[N]) { return Container; }
template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(& Container)[N]) { return Container; }
template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(&& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(&& Container)[N]) { return Container; }
/** Overloads the GetData algorithm for T::data(). */
template <typename T> requires (requires(T&& Container) { Container.data(); }) template <typename T> requires (requires(T&& Container) { Container.data(); })
FORCEINLINE constexpr decltype(auto) GetData(T&& Container) FORCEINLINE constexpr decltype(auto) GetData(T&& Container)
{ {
return Container.data(); return Container.data();
} }
/** Overloads the GetData algorithm for initializer_list. */
template <typename T> template <typename T>
FORCEINLINE constexpr decltype(auto) GetData(initializer_list<T> Container) FORCEINLINE constexpr decltype(auto) GetData(initializer_list<T> Container)
{ {
return Container.begin(); return Container.begin();
} }
/** @return The number of elements in the container. */
template <typename T> requires (requires(T&& Container) { Container.Num(); }) template <typename T> requires (requires(T&& Container) { Container.Num(); })
FORCEINLINE constexpr decltype(auto) GetNum(T&& Container) FORCEINLINE constexpr decltype(auto) GetNum(T&& Container)
{ {
return Container.Num(); return Container.Num();
} }
/** Overloads the GetNum algorithm for arrays. */
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(& Container)[N]) { return N; }
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(&& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(&& Container)[N]) { return N; }
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(& Container)[N]) { return N; }
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(&& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(&& Container)[N]) { return N; }
/** Overloads the GetNum algorithm for T::size(). */
template <typename T> requires (requires(T&& Container) { Container.size(); }) template <typename T> requires (requires(T&& Container) { Container.size(); })
FORCEINLINE constexpr decltype(auto) GetNum(T&& Container) FORCEINLINE constexpr decltype(auto) GetNum(T&& Container)
{ {
return Container.size(); return Container.size();
} }
/** Overloads the GetNum algorithm for initializer_list. */
template <typename T> template <typename T>
FORCEINLINE constexpr decltype(auto) GetNum(initializer_list<T> Container) FORCEINLINE constexpr decltype(auto) GetNum(initializer_list<T> Container)
{ {
return Container.size(); return Container.size();
} }
/** Overloads the Swap algorithm for arrays. */
template <typename T, size_t N> requires (CSwappable<TRemoveAllExtents<T>>)
FORCEINLINE constexpr void Swap(T(&A)[N], T(&B)[N])
{
for (size_t Index = 0; Index < N; ++Index)
{
Swap(A[Index], B[Index]);
}
}
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END NAMESPACE_REDCRAFT_END

View File

@ -73,18 +73,6 @@ FORCEINLINE constexpr void Swap(T& A, T& B)
B = MoveTemp(Temp); B = MoveTemp(Temp);
} }
/** Overloads the Swap algorithm for array. */
template <typename T, size_t N> requires (CMoveConstructible<T> && CMoveAssignable<T>)
FORCEINLINE constexpr void Swap(T(&A)[N], T(&B)[N])
{
for (size_t Index = 0; Index < N; ++Index)
{
T Temp = MoveTemp(A[Index]);
A[Index] = MoveTemp(B[Index]);
B[Index] = MoveTemp(Temp);
}
}
/** Replaces the value of 'A' with 'B' and returns the old value of 'A'. */ /** Replaces the value of 'A' with 'B' and returns the old value of 'A'. */
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>) template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
FORCEINLINE constexpr T Exchange(T& A, U&& B) FORCEINLINE constexpr T Exchange(T& A, U&& B)