refactor(typetraits): replaces template class type traits with concepts at all

This commit is contained in:
_Redstone_c_ 2022-05-20 23:35:36 +08:00
parent 6a5a101af4
commit ee46d84897
36 changed files with 292 additions and 554 deletions

View File

@ -1,122 +0,0 @@
#include "Testing/ConceptsTesting.h"
#include "Miscellaneous/AssertionMacros.h"
#include "Templates/Templates.h"
#include "Concepts/Concepts.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Testing)
// WARNING: The test here is not a complete test, it is only used to determine whether the environment supports the concepts
NAMESPACE_UNNAMED_BEGIN
int32 TestObject;
void TestFunction() { }
struct FTestStructA { };
struct FTestStructB : FTestStructA { int32 Member; };
struct FTestStructC { FTestStructC() { } };
struct FTestStructD { FTestStructD(const FTestStructD&) { } };
struct FTestStructE { virtual void Member() = 0; };
struct FTestStructF { int32 MemberA; private: int32 MemberB; };
struct FTestStructG { char MemberA; float MemberB; short MemberC; int MemberD; };
struct FTestStructH final : FTestStructE { virtual void Member() override { } };
struct FTestStructI { int32 MemberA; double MemberB; FTestStructI(int32 A, double B) { } FTestStructI& operator=(int32) { return *this; }; };
struct FTestStructJ { int32 MemberA; double MemberB; FTestStructJ() { }; };
struct FTestStructK { int32 MemberA; double MemberB; FTestStructK() = default; };
struct FTestStructL { int32 MemberA; double MemberB; FTestStructL() = delete; };
struct FTestStructM { int32 MemberA; double MemberB; FTestStructM(const FTestStructM&) { }; FTestStructM& operator=(const FTestStructM&) { return *this; }; };
struct FTestStructN { int32 MemberA; double MemberB; FTestStructN(const FTestStructN&) = default; FTestStructN& operator=(const FTestStructN&) = default; };
struct FTestStructO { int32 MemberA; double MemberB; FTestStructO(const FTestStructO&) = delete; FTestStructO& operator=(const FTestStructO&) = delete; };
struct FTestStructP { int32 MemberA; double MemberB; FTestStructP(FTestStructP&&) { }; FTestStructP& operator=(FTestStructP&&) { return *this; }; };
struct FTestStructQ { int32 MemberA; double MemberB; FTestStructQ(FTestStructQ&&) = default; FTestStructQ& operator=(FTestStructQ&&) = default; };
struct FTestStructR { int32 MemberA; double MemberB; FTestStructR(FTestStructR&&) = delete; FTestStructR& operator=(FTestStructR&&) = delete; };
struct FTestStructS { int32 MemberA; double MemberB; ~FTestStructS() { } };
struct FTestStructT { int32 MemberA; double MemberB; ~FTestStructT() = default; };
struct FTestStructU { int32 MemberA; double MemberB; ~FTestStructU() = delete; };
struct FTestStructV { int32 MemberA; double MemberB; virtual ~FTestStructV() { }; };
struct FTestStructW { int32 MemberA; double MemberB; operator FTestStructV() { return FTestStructV(); } };
enum ETestEnum { };
enum class ETestEnumClass { };
enum class ETestEnumClass8 : uint8 { };
enum class ETestEnumClass32 : uint32 { };
enum class ETestEnumClass64 : uint64 { };
union FTestUnion { };
NAMESPACE_UNNAMED_END
void TestConcepts()
{
// Derived.h
always_check(!(CDerivedFrom<FTestStructH, FTestStructD>));
always_check((CDerivedFrom<FTestStructH, FTestStructE>));
always_check(!(CDerivedFrom<FTestStructE, FTestStructH>));
// Common.h
always_check((CCommonWith<int32, int32>));
always_check((CCommonWith<int8, int32>));
always_check((CCommonWith<float, double>));
always_check(!(CCommonWith<FTestStructA, int32>));
always_check((CCommonReferenceWith<int8, int32>));
always_check((CCommonReferenceWith<float, int32>));
always_check((CCommonReferenceWith<float, double>));
always_check(!(CCommonReferenceWith<FTestStructA, double>));
// Comparable.h
always_check((CEqualityComparable<int32>));
always_check(!(CEqualityComparable<FTestStructA>));
always_check((CEqualityComparableWith<int32, int32>));
always_check((CEqualityComparableWith<int32, int64>));
always_check(!(CEqualityComparableWith<FTestStructA, FTestStructA>));
always_check((CTotallyOrdered<int32>));
always_check(!(CTotallyOrdered<FTestStructA>));
always_check((CTotallyOrderedWith<int32, int32>));
always_check((CTotallyOrderedWith<int32, int64>));
always_check(!(CTotallyOrderedWith<FTestStructA, FTestStructA>));
// Objects.h
always_check(CMovable<int32>);
always_check(CCopyable<int32>);
always_check(CSemiregular<int32>);
always_check(CRegular<int32>);
always_check(CMovable<FTestStructQ>);
always_check(!CCopyable<FTestStructQ>);
always_check(!CSemiregular<FTestStructQ>);
always_check(!CRegular<FTestStructQ>);
always_check(CMovable<FTestStructN>);
always_check(CCopyable<FTestStructN>);
always_check(!CSemiregular<FTestStructN>);
always_check(!CRegular<FTestStructN>);
// Swappable.h
always_check(CSwappable<int32>);
always_check(CSwappable<FTestStructG>);
always_check(CSwappable<FTestStructN>);
always_check(!CSwappable<FSingleton>);
always_check((CSwappableWith<int32&, int32&>));
}
NAMESPACE_END(Testing)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -746,8 +746,8 @@ void TestTuple()
always_check(CDefaultConstructible<Type>); always_check(CDefaultConstructible<Type>);
always_check(CTriviallyDefaultConstructible<Type>); always_check(CTriviallyDefaultConstructible<Type>);
always_check(CConstructible<Type>); always_check(CConstructibleFrom<Type>);
always_check(CTriviallyConstructible<Type>); always_check(CTriviallyConstructibleFrom<Type>);
always_check(CCopyConstructible<Type>); always_check(CCopyConstructible<Type>);
always_check(CTriviallyCopyConstructible<Type>); always_check(CTriviallyCopyConstructible<Type>);
always_check(CMoveConstructible<Type>); always_check(CMoveConstructible<Type>);

View File

@ -240,13 +240,13 @@ void TestTypeTraits()
always_check(CTriviallyDefaultConstructible<FTestStructK>); always_check(CTriviallyDefaultConstructible<FTestStructK>);
always_check(!CTriviallyDefaultConstructible<FTestStructL>); always_check(!CTriviallyDefaultConstructible<FTestStructL>);
always_check(!(CConstructible<FTestStructI, int32>)); always_check(!(CConstructibleFrom<FTestStructI, int32>));
always_check((CConstructible<FTestStructI, FTestStructI&>)); always_check((CConstructibleFrom<FTestStructI, FTestStructI&>));
always_check((CConstructible<FTestStructI, int32, double>)); always_check((CConstructibleFrom<FTestStructI, int32, double>));
always_check(!(CTriviallyConstructible<FTestStructI, int32>)); always_check(!(CTriviallyConstructibleFrom<FTestStructI, int32>));
always_check((CTriviallyConstructible<FTestStructI, FTestStructI&>)); always_check((CTriviallyConstructibleFrom<FTestStructI, FTestStructI&>));
always_check(!(CTriviallyConstructible<FTestStructI, int32, double>)); always_check(!(CTriviallyConstructibleFrom<FTestStructI, int32, double>));
always_check(CCopyConstructible<FTestStructM>); always_check(CCopyConstructible<FTestStructM>);
always_check(CCopyConstructible<FTestStructN>); always_check(CCopyConstructible<FTestStructN>);
@ -264,13 +264,13 @@ void TestTypeTraits()
always_check(CTriviallyMoveConstructible<FTestStructQ>); always_check(CTriviallyMoveConstructible<FTestStructQ>);
always_check(!CTriviallyMoveConstructible<FTestStructR>); always_check(!CTriviallyMoveConstructible<FTestStructR>);
always_check(!(CAssignable<FTestStructI, FTestStructH>)); always_check(!(CAssignableFrom<FTestStructI, FTestStructH>));
always_check((CAssignable<FTestStructI, FTestStructI&>)); always_check((CAssignableFrom<FTestStructI, FTestStructI&>));
always_check((CAssignable<FTestStructI, int32>)); always_check((CAssignableFrom<FTestStructI, int32>));
always_check(!(CTriviallyAssignable<FTestStructI, FTestStructH>)); always_check(!(CTriviallyAssignableFrom<FTestStructI, FTestStructH>));
always_check((CTriviallyAssignable<FTestStructI, FTestStructI&>)); always_check((CTriviallyAssignableFrom<FTestStructI, FTestStructI&>));
always_check(!(CTriviallyAssignable<FTestStructI, int32>)); always_check(!(CTriviallyAssignableFrom<FTestStructI, int32>));
always_check(CCopyAssignable<FTestStructM>); always_check(CCopyAssignable<FTestStructM>);
always_check(CCopyAssignable<FTestStructN>); always_check(CCopyAssignable<FTestStructN>);
@ -458,15 +458,25 @@ void TestTypeTraits()
always_check((CSameAs<int32, TCommonReference<int8, int32>::Type>)); always_check((CSameAs<int32, TCommonReference<int8, int32>::Type>));
always_check((CSameAs<int64, TCommonReference<int8, int32, int64>::Type>)); always_check((CSameAs<int64, TCommonReference<int8, int32, int64>::Type>));
always_check((CSameAs<double, TCommonReference<float, double>::Type>)); always_check((CSameAs<double, TCommonReference<float, double>::Type>));
always_check((CCommonWith<int32, int32>));
always_check((CCommonWith<int8, int32>));
always_check((CCommonWith<float, double>));
always_check(!(CCommonWith<FTestStructA, int32>));
always_check((CCommonReferenceWith<int8, int32>));
always_check((CCommonReferenceWith<float, int32>));
always_check((CCommonReferenceWith<float, double>));
always_check(!(CCommonReferenceWith<FTestStructA, double>));
// Swappable.h // Swappable.h
always_check(TIsSwappable<int32>::Value); always_check(CSwappable<int32>);
always_check(TIsSwappable<FTestStructG>::Value); always_check(CSwappable<FTestStructG>);
always_check(TIsSwappable<FTestStructN>::Value); always_check(CSwappable<FTestStructN>);
always_check(!TIsSwappable<FSingleton>::Value); always_check(!CSwappable<FSingleton>);
always_check((TIsSwappableWith<int32&, int32&>::Value)); always_check((CSwappableWith<int32&, int32&>));
// CopyQualifiers.h // CopyQualifiers.h
@ -553,6 +563,39 @@ void TestTypeTraits()
always_check(CBooleanTestable<float>); always_check(CBooleanTestable<float>);
always_check(!CBooleanTestable<FTestStructA>); always_check(!CBooleanTestable<FTestStructA>);
// Objects.h
always_check(CMovable<int32>);
always_check(CCopyable<int32>);
always_check(CSemiregular<int32>);
always_check(CRegular<int32>);
always_check(CMovable<FTestStructQ>);
always_check(!CCopyable<FTestStructQ>);
always_check(!CSemiregular<FTestStructQ>);
always_check(!CRegular<FTestStructQ>);
always_check(CMovable<FTestStructN>);
always_check(CCopyable<FTestStructN>);
always_check(!CSemiregular<FTestStructN>);
always_check(!CRegular<FTestStructN>);
// Comparable.h
always_check((CEqualityComparable<int32>));
always_check(!(CEqualityComparable<FTestStructA>));
always_check((CEqualityComparableWith<int32, int32>));
always_check((CEqualityComparableWith<int32, int64>));
always_check(!(CEqualityComparableWith<FTestStructA, FTestStructA>));
always_check((CTotallyOrdered<int32>));
always_check(!(CTotallyOrdered<FTestStructA>));
always_check((CTotallyOrderedWith<int32, int32>));
always_check((CTotallyOrderedWith<int32, int64>));
always_check(!(CTotallyOrderedWith<FTestStructA, FTestStructA>));
} }
NAMESPACE_END(Testing) NAMESPACE_END(Testing)

View File

@ -1,23 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Common.h"
#include "Templates/Utility.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CAssignableFrom =
CLValueReference<T> &&
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
requires(T A, U&& B)
{
{ A = Forward<U>(B) } -> CSameAs<T>;
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,40 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Same.h"
#include "Templates/Utility.h"
#include "Concepts/Convertible.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CCommonReferenceWith =
requires
{
typename TCommonReference<T, U>::Type;
typename TCommonReference<U, T>::Type;
} &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type> &&
CConvertibleTo<T, typename TCommonReference<T, U>::Type>&&
CConvertibleTo<U, typename TCommonReference<T, U>::Type>;
template <typename T, typename U>
concept CCommonWith =
requires
{
typename TCommonType<T, U>::Type;
typename TCommonType<U, T>::Type;
requires CSameAs<typename TCommonType<T, U>::Type, typename TCommonType<U, T>::Type>;
static_cast<TCommonType<T, U>::Type>(DeclVal<T>());
static_cast<TCommonType<T, U>::Type>(DeclVal<U>());
} &&
CCommonReferenceWith<const T&, const U&> &&
CCommonReferenceWith<typename TCommonType<T, U>::Type&, typename TCommonReference<const T&, const U&>::Type> &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,15 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Same.h"
#include "Concepts/Derived.h"
#include "Concepts/Objects.h"
#include "Concepts/Invocable.h"
#include "Concepts/Swappable.h"
#include "Concepts/Assignable.h"
#include "Concepts/Comparable.h"
#include "Concepts/BuiltinType.h"
#include "Concepts/Convertible.h"
#include "Concepts/Destructible.h"
#include "Concepts/Constructible.h"
#include "Concepts/BooleanTestable.h"

View File

@ -1,22 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Convertible.h"
#include "TypeTraits/TypeTraits.h"
#include "Concepts/Destructible.h"
#include <new>
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename... Args>
concept CConstructibleFrom = CDestructible<T> && CConstructible<T, Args...>;
template <typename T>
concept CDefaultInitializable = CConstructibleFrom<T> && requires { T{}; ::new(static_cast<void*>(nullptr)) T; };
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,15 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CDerivedFrom = CBaseOf<U, T> && CConvertibleTo<const volatile T*, const volatile U*>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,12 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -1,27 +0,0 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Common.h"
#include "Templates/Utility.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T>
concept CSwappable = requires(T& A, T& B) { Swap(A, B); };
template <typename T, typename U>
concept CSwappableWith = CCommonReferenceWith<T, U> &&
requires(T&& A, U&& B)
{
Swap(Forward<T>(A), Forward<T>(A));
Swap(Forward<U>(B), Forward<U>(B));
Swap(Forward<T>(A), Forward<U>(B));
Swap(Forward<U>(B), Forward<T>(A));
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -10,7 +10,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Memory) NAMESPACE_BEGIN(Memory)
FORCEINLINE constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); } constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); }
template <typename T> requires CIntegral<T> || CPointer<T> template <typename T> requires CIntegral<T> || CPointer<T>
FORCEINLINE constexpr T Align(T InValue, size_t Alignment) FORCEINLINE constexpr T Align(T InValue, size_t Alignment)

View File

@ -3,7 +3,6 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Memory/Memory.h" #include "Memory/Memory.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "Concepts/Comparable.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
@ -16,7 +15,7 @@ template <typename ElementType>
requires CDefaultConstructible<ElementType> requires CDefaultConstructible<ElementType>
FORCEINLINE void DefaultConstruct(ElementType* Address, size_t Count = 1) FORCEINLINE void DefaultConstruct(ElementType* Address, size_t Count = 1)
{ {
if constexpr (TIsZeroConstructible<ElementType>::Value) if constexpr (CZeroConstructible<ElementType>)
{ {
Memory::Memset(Address, 0, sizeof(ElementType) * Count); Memory::Memset(Address, 0, sizeof(ElementType) * Count);
} }
@ -32,11 +31,11 @@ FORCEINLINE void DefaultConstruct(ElementType* Address, size_t Count = 1)
} }
} }
template <typename DestinationElementType, typename SourceElementType> template <typename DestinationElementType, typename SourceElementType = DestinationElementType>
requires CConstructible<DestinationElementType, const SourceElementType&> requires CConstructibleFrom<DestinationElementType, const SourceElementType&>
FORCEINLINE void Construct(DestinationElementType* Destination, const SourceElementType* Source, size_t Count = 1) FORCEINLINE void Construct(DestinationElementType* Destination, const SourceElementType* Source, size_t Count = 1)
{ {
if constexpr (TIsBitwiseConstructible<DestinationElementType, const SourceElementType>::Value) if constexpr (CBitwiseConstructible<DestinationElementType, const SourceElementType>)
{ {
Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count); Memory::Memcpy(Destination, Source, sizeof(SourceElementType) * Count);
} }
@ -92,11 +91,11 @@ FORCEINLINE void MoveConstruct(ElementType* Destination, ElementType* Source, si
} }
} }
template <typename DestinationElementType, typename SourceElementType> template <typename DestinationElementType, typename SourceElementType = DestinationElementType>
requires CConstructible<DestinationElementType, SourceElementType&&> && CDestructible<SourceElementType> requires CConstructibleFrom<DestinationElementType, SourceElementType&&> && CDestructible<SourceElementType>
FORCEINLINE void RelocateConstruct(DestinationElementType* Destination, SourceElementType* Source, size_t Count = 1) FORCEINLINE void RelocateConstruct(DestinationElementType* Destination, SourceElementType* Source, size_t Count = 1)
{ {
if constexpr (TIsBitwiseRelocatable<DestinationElementType, SourceElementType>::Value) if constexpr (CBitwiseRelocatable<DestinationElementType, SourceElementType>)
{ {
Memory::Memmove(Destination, Source, sizeof(SourceElementType) * Count); Memory::Memmove(Destination, Source, sizeof(SourceElementType) * Count);
} }
@ -173,7 +172,7 @@ template <typename ElementType>
requires CEqualityComparable<ElementType> requires CEqualityComparable<ElementType>
FORCEINLINE bool Compare(const ElementType* LHS, const ElementType* RHS, size_t Count = 1) FORCEINLINE bool Compare(const ElementType* LHS, const ElementType* RHS, size_t Count = 1)
{ {
if constexpr (TIsBitwiseComparable<ElementType>::Value) if constexpr (CBitwiseComparable<ElementType>)
{ {
return !Memory::Memcmp(LHS, RHS, sizeof(ElementType) * Count); return !Memory::Memcmp(LHS, RHS, sizeof(ElementType) * Count);
} }

View File

@ -2,7 +2,6 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "Concepts/Concepts.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/TypeTraits.h"
#include <compare> #include <compare>

View File

@ -69,15 +69,15 @@ struct alignas(InlineAlignment) TAny
} }
template <typename T, typename... Types> requires CDestructible<typename TDecay<T>::Type> template <typename T, typename... Types> requires CDestructible<typename TDecay<T>::Type>
&& CConstructible<typename TDecay<T>::Type, Types...> && CConstructibleFrom<typename TDecay<T>::Type, Types...>
FORCEINLINE explicit TAny(TInPlaceType<T>, Types&&... Args) FORCEINLINE explicit TAny(TInPlaceType<T>, Types&&... Args)
{ {
using SelectedType = typename TDecay<T>::Type; using SelectedType = typename TDecay<T>::Type;
EmplaceImpl<SelectedType>(Forward<Types>(Args)...); EmplaceImpl<SelectedType>(Forward<Types>(Args)...);
} }
template <typename T> requires (!CSameAs<typename TDecay<T>::Type, TAny>) && (!TIsTInPlaceType<typename TDecay<T>::Type>::Value) template <typename T> requires (!CSameAs<typename TDecay<T>::Type, TAny>) && (!CTInPlaceType<typename TDecay<T>::Type>)
&& CDestructible<typename TDecay<T>::Type> && CConstructible<typename TDecay<T>::Type, T&&> && CDestructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&>
FORCEINLINE TAny(T&& InValue) : TAny(InPlaceType<typename TDecay<T>::Type>, Forward<T>(InValue)) FORCEINLINE TAny(T&& InValue) : TAny(InPlaceType<typename TDecay<T>::Type>, Forward<T>(InValue))
{ } { }
@ -184,8 +184,8 @@ struct alignas(InlineAlignment) TAny
return *this; return *this;
} }
template <typename T> requires (!CSameAs<typename TDecay<T>::Type, TAny>) && (!TIsTInPlaceType<typename TDecay<T>::Type>::Value) template <typename T> requires (!CSameAs<typename TDecay<T>::Type, TAny>) && (!CTInPlaceType<typename TDecay<T>::Type>)
&& CDestructible<typename TDecay<T>::Type> && CConstructible<typename TDecay<T>::Type, T&&> && CDestructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&>
FORCEINLINE TAny& operator=(T&& InValue) FORCEINLINE TAny& operator=(T&& InValue)
{ {
using SelectedType = typename TDecay<T>::Type; using SelectedType = typename TDecay<T>::Type;
@ -204,7 +204,7 @@ struct alignas(InlineAlignment) TAny
} }
template <typename T, typename... Types> requires CDestructible<typename TDecay<T>::Type> template <typename T, typename... Types> requires CDestructible<typename TDecay<T>::Type>
&& CConstructible<typename TDecay<T>::Type, T&&> && CConstructibleFrom<typename TDecay<T>::Type, T&&>
FORCEINLINE typename TDecay<T>::Type& Emplace(Types&&... Args) FORCEINLINE typename TDecay<T>::Type& Emplace(Types&&... Args)
{ {
ResetImpl(); ResetImpl();
@ -430,9 +430,15 @@ constexpr bool operator==(const TAny<InlineSize, InlineAlignment>& LHS, FInvalid
return !LHS.IsValid(); return !LHS.IsValid();
} }
NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTAny : FFalse { }; template <typename T> struct TIsTAny : FFalse { };
template <size_t InlineSize, size_t InlineAlignment> struct TIsTAny<TAny<InlineSize, InlineAlignment>> : FTrue { }; template <size_t InlineSize, size_t InlineAlignment> struct TIsTAny<TAny<InlineSize, InlineAlignment>> : FTrue { };
NAMESPACE_PRIVATE_END
template <typename T> concept CTAny = NAMESPACE_PRIVATE::TIsTAny<T>::Value;
using FAny = TAny<ANY_DEFAULT_INLINE_SIZE>; using FAny = TAny<ANY_DEFAULT_INLINE_SIZE>;
static_assert(sizeof(FAny) == 64, "The byte size of FAny is unexpected"); static_assert(sizeof(FAny) == 64, "The byte size of FAny is unexpected");

View File

@ -28,6 +28,8 @@ struct TFunction;
template <typename F, size_t InlineSize, size_t InlineAlignment> requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment)) template <typename F, size_t InlineSize, size_t InlineAlignment> requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment))
struct TUniqueFunction; struct TUniqueFunction;
NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTFunctionRef : FFalse { }; template <typename T> struct TIsTFunctionRef : FFalse { };
template <typename F> struct TIsTFunctionRef<TFunctionRef<F>> : FTrue { }; template <typename F> struct TIsTFunctionRef<TFunctionRef<F>> : FTrue { };
@ -37,12 +39,18 @@ template <typename F, size_t I, size_t J> struct TIsTFunction<TFunction<F, I, J>
template <typename T> struct TIsTUniqueFunction : FFalse { }; template <typename T> struct TIsTUniqueFunction : FFalse { };
template <typename F, size_t I, size_t J> struct TIsTUniqueFunction<TUniqueFunction<F, I, J>> : FTrue { }; template <typename F, size_t I, size_t J> struct TIsTUniqueFunction<TUniqueFunction<F, I, J>> : FTrue { };
NAMESPACE_PRIVATE_END
template <typename T> concept CTFunctionRef = NAMESPACE_PRIVATE::TIsTFunctionRef<T>::Value;
template <typename T> concept CTFunction = NAMESPACE_PRIVATE::TIsTFunction<T>::Value;
template <typename T> concept CTUniqueFunction = NAMESPACE_PRIVATE::TIsTUniqueFunction<T>::Value;
NAMESPACE_PRIVATE_BEGIN NAMESPACE_PRIVATE_BEGIN
template <typename T> template <typename T>
constexpr bool FunctionIsBound(const T& Func) constexpr bool FunctionIsBound(const T& Func)
{ {
if constexpr (CPointer<T> || CMemberPointer<T> || TIsTFunctionRef<T>::Value || TIsTFunction<T>::Value || TIsTUniqueFunction<T>::Value) if constexpr (CPointer<T> || CMemberPointer<T> || CTFunctionRef<T> || CTFunction<T> || CTUniqueFunction<T>)
{ {
return !!Func; return !!Func;
} }
@ -241,7 +249,7 @@ public:
TFunctionRef& operator=(const TFunctionRef& InValue) = delete; TFunctionRef& operator=(const TFunctionRef& InValue) = delete;
TFunctionRef& operator=(TFunctionRef&& InValue) = delete; TFunctionRef& operator=(TFunctionRef&& InValue) = delete;
template <typename T> requires (!TIsTFunctionRef<typename TDecay<T>::Type>::Value) && (!TIsTInPlaceType<typename TDecay<T>::Type>::Value) template <typename T> requires (!CTFunctionRef<typename TDecay<T>::Type>) && (!CTInPlaceType<typename TDecay<T>::Type>)
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value && NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
FORCEINLINE TFunctionRef(T&& InValue) FORCEINLINE TFunctionRef(T&& InValue)
{ {
@ -294,9 +302,9 @@ public:
return *this; return *this;
} }
template <typename T> requires (!TIsTInPlaceType<typename TDecay<T>::Type>::Value) template <typename T> requires (!CTInPlaceType<typename TDecay<T>::Type>)
&& (!TIsTFunctionRef<typename TDecay<T>::Type>::Value) && (!TIsTFunction<typename TDecay<T>::Type>::Value) && (!TIsTUniqueFunction<typename TDecay<T>::Type>::Value) && (!CTFunctionRef<typename TDecay<T>::Type>) && (!CTFunction<typename TDecay<T>::Type>) && (!CTUniqueFunction<typename TDecay<T>::Type>)
&& CConstructible<typename TDecay<T>::Type, T&&> && CCopyConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&> && CCopyConstructible<typename TDecay<T>::Type>
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value && NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
FORCEINLINE TFunction(T&& InValue) FORCEINLINE TFunction(T&& InValue)
{ {
@ -306,7 +314,7 @@ public:
} }
template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& CConstructible<typename TDecay<T>::Type, ArgTypes...> && CCopyConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, ArgTypes...> && CCopyConstructible<typename TDecay<T>::Type>
FORCEINLINE TFunction(TInPlaceType<T>, ArgTypes&&... Args) FORCEINLINE TFunction(TInPlaceType<T>, ArgTypes&&... Args)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;
@ -316,8 +324,8 @@ public:
constexpr TFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; } constexpr TFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; }
template <typename T> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& (!TIsTFunctionRef<typename TDecay<T>::Type>::Value) && (!TIsTFunction<typename TDecay<T>::Type>::Value) && (!TIsTUniqueFunction<typename TDecay<T>::Type>::Value) && (!CTFunctionRef<typename TDecay<T>::Type>) && (!CTFunction<typename TDecay<T>::Type>) && (!CTUniqueFunction<typename TDecay<T>::Type>)
&& CConstructible<typename TDecay<T>::Type, T&&> && CCopyConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&> && CCopyConstructible<typename TDecay<T>::Type>
FORCEINLINE TFunction& operator=(T&& InValue) FORCEINLINE TFunction& operator=(T&& InValue)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;
@ -329,7 +337,7 @@ public:
} }
template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& CConstructible<typename TDecay<T>::Type, ArgTypes...>&& CCopyConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, ArgTypes...>&& CCopyConstructible<typename TDecay<T>::Type>
FORCEINLINE typename TDecay<T>::Type& Emplace(ArgTypes&&... Args) FORCEINLINE typename TDecay<T>::Type& Emplace(ArgTypes&&... Args)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;
@ -397,9 +405,9 @@ public:
return *this; return *this;
} }
template <typename T> requires (!TIsTInPlaceType<typename TDecay<T>::Type>::Value) template <typename T> requires (!CTInPlaceType<typename TDecay<T>::Type>)
&& (!TIsTFunctionRef<typename TDecay<T>::Type>::Value) && (!TIsTFunction<typename TDecay<T>::Type>::Value) && (!TIsTUniqueFunction<typename TDecay<T>::Type>::Value) && (!CTFunctionRef<typename TDecay<T>::Type>) && (!CTFunction<typename TDecay<T>::Type>) && (!CTUniqueFunction<typename TDecay<T>::Type>)
&& CConstructible<typename TDecay<T>::Type, T&&> && CMoveConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&> && CMoveConstructible<typename TDecay<T>::Type>
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value && NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
FORCEINLINE TUniqueFunction(T&& InValue) FORCEINLINE TUniqueFunction(T&& InValue)
{ {
@ -409,7 +417,7 @@ public:
} }
template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& CConstructible<typename TDecay<T>::Type, ArgTypes...> && CMoveConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, ArgTypes...> && CMoveConstructible<typename TDecay<T>::Type>
FORCEINLINE TUniqueFunction(TInPlaceType<T>, ArgTypes&&... Args) FORCEINLINE TUniqueFunction(TInPlaceType<T>, ArgTypes&&... Args)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;
@ -419,8 +427,8 @@ public:
constexpr TUniqueFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; } constexpr TUniqueFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; }
template <typename T> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& (!TIsTFunctionRef<typename TDecay<T>::Type>::Value) && (!TIsTFunction<typename TDecay<T>::Type>::Value) && (!TIsTUniqueFunction<typename TDecay<T>::Type>::Value) && (!CTFunctionRef<typename TDecay<T>::Type>) && (!CTFunction<typename TDecay<T>::Type>) && (!CTUniqueFunction<typename TDecay<T>::Type>)
&& CConstructible<typename TDecay<T>::Type, T&&>&& CMoveConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, T&&>&& CMoveConstructible<typename TDecay<T>::Type>
FORCEINLINE TUniqueFunction& operator=(T&& InValue) FORCEINLINE TUniqueFunction& operator=(T&& InValue)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;
@ -432,7 +440,7 @@ public:
} }
template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value template <typename T, typename... ArgTypes> requires NAMESPACE_PRIVATE::TIsInvocableSignature<F, typename TDecay<T>::Type>::Value
&& CConstructible<typename TDecay<T>::Type, ArgTypes...>&& CMoveConstructible<typename TDecay<T>::Type> && CConstructibleFrom<typename TDecay<T>::Type, ArgTypes...>&& CMoveConstructible<typename TDecay<T>::Type>
FORCEINLINE typename TDecay<T>::Type& Emplace(ArgTypes&&... Args) FORCEINLINE typename TDecay<T>::Type& Emplace(ArgTypes&&... Args)
{ {
using DecayedType = typename TDecay<T>::Type; using DecayedType = typename TDecay<T>::Type;

View File

@ -3,7 +3,6 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "Templates/TypeHash.h" #include "Templates/TypeHash.h"
#include "Concepts/Comparable.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/TypeTraits.h"
#include "Miscellaneous/Compare.h" #include "Miscellaneous/Compare.h"
#include "Miscellaneous/AssertionMacros.h" #include "Miscellaneous/AssertionMacros.h"
@ -19,18 +18,18 @@ private:
template <typename T> template <typename T>
struct TAllowUnwrapping : TBoolConstant<!( struct TAllowUnwrapping : TBoolConstant<!(
CConstructible<OptionalType, TOptional<T>& > CConstructibleFrom<OptionalType, TOptional<T>& >
|| CConstructible<OptionalType, const TOptional<T>& > || CConstructibleFrom<OptionalType, const TOptional<T>& >
|| CConstructible<OptionalType, TOptional<T>&&> || CConstructibleFrom<OptionalType, TOptional<T>&&>
|| CConstructible<OptionalType, const TOptional<T>&&> || CConstructibleFrom<OptionalType, const TOptional<T>&&>
|| CConvertibleTo< TOptional<T>&, OptionalType> || CConvertibleTo< TOptional<T>&, OptionalType>
|| CConvertibleTo<const TOptional<T>&, OptionalType> || CConvertibleTo<const TOptional<T>&, OptionalType>
|| CConvertibleTo< TOptional<T>&&, OptionalType> || CConvertibleTo< TOptional<T>&&, OptionalType>
|| CConvertibleTo<const TOptional<T>&&, OptionalType> || CConvertibleTo<const TOptional<T>&&, OptionalType>
|| CAssignable<OptionalType&, TOptional<T>& > || CAssignableFrom<OptionalType&, TOptional<T>& >
|| CAssignable<OptionalType&, const TOptional<T>& > || CAssignableFrom<OptionalType&, const TOptional<T>& >
|| CAssignable<OptionalType&, TOptional<T>&&> || CAssignableFrom<OptionalType&, TOptional<T>&&>
|| CAssignable<OptionalType&, const TOptional<T>&&> || CAssignableFrom<OptionalType&, const TOptional<T>&&>
)> { }; )> { };
public: public:
@ -41,14 +40,14 @@ public:
constexpr TOptional(FInvalid) : TOptional() { } constexpr TOptional(FInvalid) : TOptional() { }
template <typename... Types> requires CConstructible<OptionalType, Types...> template <typename... Types> requires CConstructibleFrom<OptionalType, Types...>
constexpr explicit TOptional(FInPlace, Types&&... Args) constexpr explicit TOptional(FInPlace, Types&&... Args)
: bIsValid(true) : bIsValid(true)
{ {
new(&Value) OptionalType(Forward<Types>(Args)...); new(&Value) OptionalType(Forward<Types>(Args)...);
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&>
&& (!CSameAs<typename TRemoveCVRef<T>::Type, FInPlace>) && (!CSameAs<typename TRemoveCVRef<T>::Type, TOptional>) && (!CSameAs<typename TRemoveCVRef<T>::Type, FInPlace>) && (!CSameAs<typename TRemoveCVRef<T>::Type, TOptional>)
constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue) constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue)
: TOptional(InPlace, Forward<T>(InValue)) : TOptional(InPlace, Forward<T>(InValue))
@ -66,14 +65,14 @@ public:
if (InValue.IsValid()) new(&Value) OptionalType(MoveTemp(InValue.GetValue())); if (InValue.IsValid()) new(&Value) OptionalType(MoveTemp(InValue.GetValue()));
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, const T&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value
constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue) constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new(&Value) OptionalType(InValue.GetValue()); if (InValue.IsValid()) new(&Value) OptionalType(InValue.GetValue());
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&> && TAllowUnwrapping<T>::Value
constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(TOptional<T>&& InValue) constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(TOptional<T>&& InValue)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
@ -125,7 +124,7 @@ public:
return *this; return *this;
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, const T&> && CAssignable<OptionalType&, const T&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
constexpr TOptional& operator=(const TOptional<T>& InValue) constexpr TOptional& operator=(const TOptional<T>& InValue)
{ {
if (!InValue.IsValid()) if (!InValue.IsValid())
@ -144,7 +143,7 @@ public:
return *this; return *this;
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> && CAssignable<OptionalType&, T&&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&> && TAllowUnwrapping<T>::Value
constexpr TOptional& operator=(TOptional<T>&& InValue) constexpr TOptional& operator=(TOptional<T>&& InValue)
{ {
if (!InValue.IsValid()) if (!InValue.IsValid())
@ -163,7 +162,7 @@ public:
return *this; return *this;
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> && CAssignable<OptionalType&, T&&> template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>
constexpr TOptional& operator=(T&& InValue) constexpr TOptional& operator=(T&& InValue)
{ {
if (IsValid()) GetValue() = Forward<T>(InValue); if (IsValid()) GetValue() = Forward<T>(InValue);
@ -176,7 +175,7 @@ public:
return *this; return *this;
} }
template <typename... ArgTypes> requires CConstructible<OptionalType, ArgTypes...> template <typename... ArgTypes> requires CConstructibleFrom<OptionalType, ArgTypes...>
constexpr OptionalType& Emplace(ArgTypes&&... Args) constexpr OptionalType& Emplace(ArgTypes&&... Args)
{ {
Reset(); Reset();
@ -223,7 +222,7 @@ public:
return NAMESPACE_REDCRAFT::GetTypeHash(GetValue()); return NAMESPACE_REDCRAFT::GetTypeHash(GetValue());
} }
template <typename T> requires CMoveConstructible<OptionalType> && TIsSwappable<OptionalType>::Value template <typename T> requires CMoveConstructible<OptionalType> && CSwappable<OptionalType>
constexpr void Swap(TOptional& InValue) constexpr void Swap(TOptional& InValue)
{ {
if (!IsValid() && !InValue.IsValid()) return; if (!IsValid() && !InValue.IsValid()) return;
@ -289,21 +288,27 @@ constexpr TOptional<typename TDecay<T>::Type> MakeOptional(FInvalid)
return TOptional<typename TDecay<T>::Type>(Invalid); return TOptional<typename TDecay<T>::Type>(Invalid);
} }
template <typename T> requires CDestructible<T> && CConstructible<T, T&&> template <typename T> requires CDestructible<T> && CConstructibleFrom<T, T&&>
constexpr TOptional<T> MakeOptional(T&& InValue) constexpr TOptional<T> MakeOptional(T&& InValue)
{ {
return TOptional<T>(Forward<T>(InValue)); return TOptional<T>(Forward<T>(InValue));
} }
template <typename T, typename... Types> requires CDestructible<T> && CConstructible<T, Types...> template <typename T, typename... Types> requires CDestructible<T> && CConstructibleFrom<T, Types...>
constexpr TOptional<T> MakeOptional(Types&&... Args) constexpr TOptional<T> MakeOptional(Types&&... Args)
{ {
return TOptional<T>(InPlace, Forward<T>(Args)...); return TOptional<T>(InPlace, Forward<T>(Args)...);
} }
NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTOptional : FFalse { }; template <typename T> struct TIsTOptional : FFalse { };
template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { }; template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { };
NAMESPACE_PRIVATE_END
template <typename T> concept CTOptional = NAMESPACE_PRIVATE::TIsTOptional<T>::Value;
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END NAMESPACE_REDCRAFT_END

View File

@ -99,9 +99,15 @@ constexpr TReferenceWrapper<const T> Ref(TReferenceWrapper<T> InValue)
return Ref(InValue.Get()); return Ref(InValue.Get());
} }
NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTReferenceWrapper : FFalse { }; template <typename T> struct TIsTReferenceWrapper : FFalse { };
template <typename T> struct TIsTReferenceWrapper<TReferenceWrapper<T>> : FTrue { }; template <typename T> struct TIsTReferenceWrapper<TReferenceWrapper<T>> : FTrue { };
NAMESPACE_PRIVATE_END
template <typename T> concept CTReferenceWrapper = NAMESPACE_PRIVATE::TIsTReferenceWrapper<T>::Value;
template <typename T> struct TUnwrapReference { using Type = T; }; template <typename T> struct TUnwrapReference { using Type = T; };
template <typename T> struct TUnwrapReference<TReferenceWrapper<T>> { using Type = T&; }; template <typename T> struct TUnwrapReference<TReferenceWrapper<T>> { using Type = T&; };
@ -115,19 +121,19 @@ private:
using OptionalType = TReferenceWrapper<ReferencedType>; using OptionalType = TReferenceWrapper<ReferencedType>;
template <typename T> template <typename T>
struct TAllowUnwrapping : TBoolConstant<!( struct TAllowUnwrapping : TBoolConstant < !(
CConstructible<OptionalType, TOptional<T>& > CConstructibleFrom<OptionalType, TOptional<T>& >
|| CConstructible<OptionalType, const TOptional<T>& > || CConstructibleFrom<OptionalType, const TOptional<T>& >
|| CConstructible<OptionalType, TOptional<T>&&> || CConstructibleFrom<OptionalType, TOptional<T>&&>
|| CConstructible<OptionalType, const TOptional<T>&&> || CConstructibleFrom<OptionalType, const TOptional<T>&&>
|| CConvertibleTo< TOptional<T>&, OptionalType> || CConvertibleTo< TOptional<T>&, OptionalType>
|| CConvertibleTo<const TOptional<T>&, OptionalType> || CConvertibleTo<const TOptional<T>&, OptionalType>
|| CConvertibleTo< TOptional<T>&&, OptionalType> || CConvertibleTo< TOptional<T>&&, OptionalType>
|| CConvertibleTo<const TOptional<T>&&, OptionalType> || CConvertibleTo<const TOptional<T>&&, OptionalType>
|| CAssignable<OptionalType&, TOptional<T>& > || CAssignableFrom<OptionalType&, TOptional<T>& >
|| CAssignable<OptionalType&, const TOptional<T>& > || CAssignableFrom<OptionalType&, const TOptional<T>& >
|| CAssignable<OptionalType&, TOptional<T>&&> || CAssignableFrom<OptionalType&, TOptional<T>&&>
|| CAssignable<OptionalType&, const TOptional<T>&&> || CAssignableFrom<OptionalType&, const TOptional<T>&&>
)> { }; )> { };
public: public:
@ -138,12 +144,12 @@ public:
constexpr TOptional(FInvalid) : TOptional() { } constexpr TOptional(FInvalid) : TOptional() { }
template <typename... Types> requires CConstructible<OptionalType, Types...> template <typename... Types> requires CConstructibleFrom<OptionalType, Types...>
constexpr explicit TOptional(FInPlace, Types&&... Args) constexpr explicit TOptional(FInPlace, Types&&... Args)
: Reference(Forward<Types>(Args)...) : Reference(Forward<Types>(Args)...)
{ } { }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&>
&& (!CSameAs<typename TRemoveCVRef<T>::Type, FInPlace>) && (!CSameAs<typename TRemoveCVRef<T>::Type, TOptional>) && (!CSameAs<typename TRemoveCVRef<T>::Type, FInPlace>) && (!CSameAs<typename TRemoveCVRef<T>::Type, TOptional>)
constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue) constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue)
: TOptional(InPlace, Forward<T>(InValue)) : TOptional(InPlace, Forward<T>(InValue))
@ -152,7 +158,7 @@ public:
TOptional(const TOptional& InValue) = default; TOptional(const TOptional& InValue) = default;
TOptional(TOptional&& InValue) = default; TOptional(TOptional&& InValue) = default;
template <typename T = OptionalType> requires CConstructible<OptionalType, const T&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value
constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue) constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue)
: Reference(InValue.Reference) : Reference(InValue.Reference)
{ } { }
@ -162,21 +168,21 @@ public:
TOptional& operator=(const TOptional& InValue) = default; TOptional& operator=(const TOptional& InValue) = default;
TOptional& operator=(TOptional&& InValue) = default; TOptional& operator=(TOptional&& InValue) = default;
template <typename T = OptionalType> requires CConstructible<OptionalType, const T&> && CAssignable<OptionalType&, const T&> && TAllowUnwrapping<T>::Value template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
constexpr TOptional& operator=(const TOptional<T>& InValue) constexpr TOptional& operator=(const TOptional<T>& InValue)
{ {
Reference = InValue.Reference; Reference = InValue.Reference;
return *this; return *this;
} }
template <typename T = OptionalType> requires CConstructible<OptionalType, T&&> && CAssignable<OptionalType&, T&&> template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>
constexpr TOptional& operator=(T&& InValue) constexpr TOptional& operator=(T&& InValue)
{ {
Reference = InValue; Reference = InValue;
return *this; return *this;
} }
template <typename... ArgTypes> requires CConstructible<OptionalType, ArgTypes...> template <typename... ArgTypes> requires CConstructibleFrom<OptionalType, ArgTypes...>
constexpr OptionalType& Emplace(ArgTypes&&... Args) constexpr OptionalType& Emplace(ArgTypes&&... Args)
{ {
Reference = TReferenceWrapper<ReferencedType>(Forward<ArgTypes>(Args)...); Reference = TReferenceWrapper<ReferencedType>(Forward<ArgTypes>(Args)...);

View File

@ -236,23 +236,23 @@ public:
TTuple() = default; TTuple() = default;
template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize) template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize)
&& (true && ... && CConstructible<Types, ArgTypes&&>) && (true && ... && CConstructibleFrom<Types, ArgTypes&&>)
&& (true && ... && CConvertibleTo<ArgTypes&&, Types>) && (true && ... && CConvertibleTo<ArgTypes&&, Types>)
constexpr TTuple(ArgTypes&&... Args) constexpr TTuple(ArgTypes&&... Args)
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...) : Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
{ } { }
template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize) template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize)
&& (true && ... && CConstructible<Types, ArgTypes&&>) && (true && ... && CConstructibleFrom<Types, ArgTypes&&>)
&& (!(true && ... && CConvertibleTo<ArgTypes&&, Types>)) && (!(true && ... && CConvertibleTo<ArgTypes&&, Types>))
constexpr explicit TTuple(ArgTypes&&... Args) constexpr explicit TTuple(ArgTypes&&... Args)
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...) : Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CConstructible<Types, const OtherTypes&>) && (true && ... && CConstructibleFrom<Types, const OtherTypes&>)
&& ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type> && ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type>
|| CConstructible<typename TElementType<0>::Type, const TTuple<OtherTypes...>&> || CConstructibleFrom<typename TElementType<0>::Type, const TTuple<OtherTypes...>&>
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>)) || CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
&& (true && ... && CConvertibleTo<OtherTypes&&, Types>) && (true && ... && CConvertibleTo<OtherTypes&&, Types>)
constexpr TTuple(const TTuple<OtherTypes...>& InValue) constexpr TTuple(const TTuple<OtherTypes...>& InValue)
@ -260,9 +260,9 @@ public:
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CConstructible<Types, const OtherTypes&>) && (true && ... && CConstructibleFrom<Types, const OtherTypes&>)
&& ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type> && ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type>
|| CConstructible<typename TElementType<0>::Type, const TTuple<OtherTypes...>&> || CConstructibleFrom<typename TElementType<0>::Type, const TTuple<OtherTypes...>&>
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>)) || CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
&& (!(true && ... && CConvertibleTo<OtherTypes&&, Types>)) && (!(true && ... && CConvertibleTo<OtherTypes&&, Types>))
constexpr explicit TTuple(const TTuple<OtherTypes...>& InValue) constexpr explicit TTuple(const TTuple<OtherTypes...>& InValue)
@ -270,9 +270,9 @@ public:
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CConstructible<Types, OtherTypes&&>) && (true && ... && CConstructibleFrom<Types, OtherTypes&&>)
&& ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type> && ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type>
|| CConstructible<typename TElementType<0>::Type, TTuple<OtherTypes...>&&> || CConstructibleFrom<typename TElementType<0>::Type, TTuple<OtherTypes...>&&>
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>)) || CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
&& (true && ... && CConvertibleTo<OtherTypes&&, Types>) && (true && ... && CConvertibleTo<OtherTypes&&, Types>)
constexpr TTuple(TTuple<OtherTypes...>&& InValue) constexpr TTuple(TTuple<OtherTypes...>&& InValue)
@ -280,9 +280,9 @@ public:
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CConstructible<Types, OtherTypes&&>) && (true && ... && CConstructibleFrom<Types, OtherTypes&&>)
&& ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type> && ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type>
|| CConstructible<typename TElementType<0>::Type, TTuple<OtherTypes...>&&> || CConstructibleFrom<typename TElementType<0>::Type, TTuple<OtherTypes...>&&>
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>)) || CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
&& (!(true && ... && CConvertibleTo<OtherTypes&&, Types>)) && (!(true && ... && CConvertibleTo<OtherTypes&&, Types>))
constexpr explicit TTuple(TTuple<OtherTypes...>&& InValue) constexpr explicit TTuple(TTuple<OtherTypes...>&& InValue)
@ -293,7 +293,7 @@ public:
TTuple(TTuple&&) = default; TTuple(TTuple&&) = default;
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CAssignable<Types&, const OtherTypes&>) && (true && ... && CAssignableFrom<Types&, const OtherTypes&>)
constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue) constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
{ {
Helper::Assign(*this, InValue); Helper::Assign(*this, InValue);
@ -301,7 +301,7 @@ public:
} }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
&& (true && ... && CAssignable<Types&, OtherTypes&&>) && (true && ... && CAssignableFrom<Types&, OtherTypes&&>)
constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue) constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
{ {
Helper::Assign(*this, MoveTemp(InValue)); Helper::Assign(*this, MoveTemp(InValue));
@ -365,21 +365,21 @@ public:
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() volatile& { return Helper::template Construct<T>(static_cast< volatile TTuple& >(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() volatile& { return Helper::template Construct<T>(static_cast< volatile TTuple& >(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() const volatile& { return Helper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const volatile& { return Helper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() && { return Helper::template Construct<T>(static_cast< TTuple&&>(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() && { return Helper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() const && { return Helper::template Construct<T>(static_cast<const TTuple&&>(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const && { return Helper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() volatile&& { return Helper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() volatile&& { return Helper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
template <typename T> requires CConstructible<T, Types...> constexpr T Construct() const volatile&& { return Helper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const volatile&& { return Helper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Types>) constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Types>)
{ {
return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t { return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue<Indices>())...); } (TMakeIndexSequence<ElementSize>()); return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t { return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue<Indices>())...); } (TMakeIndexSequence<ElementSize>());
} }
constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Types>&& TIsSwappable<Types>::Value)) constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Types>&& CSwappable<Types>))
{ {
[&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>) { ((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...); } (TMakeIndexSequence<ElementSize>()); [&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>) { ((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...); } (TMakeIndexSequence<ElementSize>());
} }
@ -392,16 +392,22 @@ TTuple(Types...) -> TTuple<Types...>;
template <typename T, typename U> template <typename T, typename U>
using TPair = TTuple<T, U>; using TPair = TTuple<T, U>;
NAMESPACE_PRIVATE_BEGIN
template <typename T > struct TIsTTuple : FFalse { }; template <typename T > struct TIsTTuple : FFalse { };
template <typename... Types> struct TIsTTuple<TTuple<Types...>> : FTrue { }; template <typename... Types> struct TIsTTuple<TTuple<Types...>> : FTrue { };
template <typename TupleType> requires TIsTTuple<typename TRemoveCVRef<TupleType>::Type>::Value NAMESPACE_PRIVATE_END
template <typename T> concept CTTuple = NAMESPACE_PRIVATE::TIsTTuple<T>::Value;
template <typename TupleType> requires CTTuple<typename TRemoveCVRef<TupleType>::Type>
struct TTupleElementSize : TConstant<size_t, TRemoveCVRef<TupleType>::Type::ElementSize> { }; struct TTupleElementSize : TConstant<size_t, TRemoveCVRef<TupleType>::Type::ElementSize> { };
template <size_t I, typename TupleType> requires TIsTTuple<typename TRemoveCVRef<TupleType>::Type>::Value template <size_t I, typename TupleType> requires CTTuple<typename TRemoveCVRef<TupleType>::Type>
struct TTupleElementType { using Type = typename TCopyCVRef<typename TRemoveReference<TupleType>::Type, typename TRemoveCVRef<TupleType>::Type::template TElementType<I>::Type>::Type; }; struct TTupleElementType { using Type = typename TCopyCVRef<typename TRemoveReference<TupleType>::Type, typename TRemoveCVRef<TupleType>::Type::template TElementType<I>::Type>::Type; };
template <typename T, typename TupleType> requires TIsTTuple<typename TRemoveCVRef<TupleType>::Type>::Value template <typename T, typename TupleType> requires CTTuple<typename TRemoveCVRef<TupleType>::Type>
struct TTupleElementIndex : TupleType::template TElementIndex<T> { }; struct TTupleElementIndex : TupleType::template TElementIndex<T> { };
template <typename... Types> template <typename... Types>
@ -540,10 +546,10 @@ struct TTupleVisitImpl<TIndexSequence<>>
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
template <typename... TTupleTypes> requires (true && ... && (TIsTTuple<typename TRemoveCVRef<TTupleTypes>::Type>::Value)) template <typename... TTupleTypes> requires (true && ... && (CTTuple<typename TRemoveCVRef<TTupleTypes>::Type>))
struct TTupleCatResult { using Type = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<typename TRemoveReference<TTupleTypes>::Type..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type; }; struct TTupleCatResult { using Type = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<typename TRemoveReference<TTupleTypes>::Type..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type; };
template <typename... TTupleTypes> requires (true && ... && (TIsTTuple<typename TRemoveCVRef<TTupleTypes>::Type>::Value)) template <typename... TTupleTypes> requires (true && ... && (CTTuple<typename TRemoveCVRef<TTupleTypes>::Type>))
constexpr auto TupleCat(TTupleTypes&&... Args) constexpr auto TupleCat(TTupleTypes&&... Args)
{ {
using R = typename TTupleCatResult<TTupleTypes...>::Type; using R = typename TTupleCatResult<TTupleTypes...>::Type;

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Concepts/Same.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "TypeTraits/PrimaryType.h" #include "TypeTraits/PrimaryType.h"
#include "TypeTraits/Miscellaneous.h" #include "TypeTraits/Miscellaneous.h"

View File

@ -77,7 +77,7 @@ constexpr void Swap(T& A, T& B)
} }
} }
template <typename T, typename U = T> requires CMoveConstructible<T> && CAssignable<T&, U> template <typename T, typename U = T> requires CMoveConstructible<T> && CAssignableFrom<T&, U>
constexpr T Exchange(T& A, U&& B) constexpr T Exchange(T& A, U&& B)
{ {
T Temp = MoveTemp(A); T Temp = MoveTemp(A);

View File

@ -49,7 +49,7 @@ struct TVariantSelectedType;
template <typename T, typename U, typename... Types> template <typename T, typename U, typename... Types>
struct TVariantSelectedType<T, U, Types...> struct TVariantSelectedType<T, U, Types...>
{ {
using TypeAlternativeA = typename TConditional<CConstructible<U, T&&>, U, void>::Type; using TypeAlternativeA = typename TConditional<CConstructibleFrom<U, T&&>, U, void>::Type;
using TypeAlternativeB = typename TVariantSelectedType<T, Types...>::Type; using TypeAlternativeB = typename TVariantSelectedType<T, Types...>::Type;
using Type = typename TConditional<CSameAs<typename TRemoveCVRef<TypeAlternativeA>::Type, void>, TypeAlternativeB, using Type = typename TConditional<CSameAs<typename TRemoveCVRef<TypeAlternativeA>::Type, void>, TypeAlternativeB,
@ -103,7 +103,7 @@ struct TVariant
} }
template <size_t I, typename... ArgTypes> requires (I < AlternativeSize) template <size_t I, typename... ArgTypes> requires (I < AlternativeSize)
&& CConstructible<typename TAlternativeType<I>::Type, ArgTypes...> && CConstructibleFrom<typename TAlternativeType<I>::Type, ArgTypes...>
constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args) constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args)
: TypeIndex(I) : TypeIndex(I)
{ {
@ -112,13 +112,13 @@ struct TVariant
} }
template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE) template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE)
&& CConstructible<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...> && CConstructibleFrom<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...>
constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args) constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args)
: TVariant(InPlaceIndex<TAlternativeIndex<T>::Value>, Forward<ArgTypes>(Args)...) : TVariant(InPlaceIndex<TAlternativeIndex<T>::Value>, Forward<ArgTypes>(Args)...)
{ } { }
template <typename T> requires NAMESPACE_PRIVATE::TVariantSelectedType<typename TRemoveReference<T>::Type, Types...>::Value template <typename T> requires NAMESPACE_PRIVATE::TVariantSelectedType<typename TRemoveReference<T>::Type, Types...>::Value
&& (!TIsTInPlaceType<typename TRemoveCVRef<T>::Type>::Value) && (!TIsTInPlaceIndex<typename TRemoveCVRef<T>::Type>::Value) && (!CTInPlaceType<typename TRemoveCVRef<T>::Type>) && (!CTInPlaceIndex<typename TRemoveCVRef<T>::Type>)
&& (!CSameAs<typename TRemoveCVRef<T>::Type, TVariant>) && (!CSameAs<typename TRemoveCVRef<T>::Type, TVariant>)
constexpr TVariant(T&& InValue) : TVariant(InPlaceType<typename NAMESPACE_PRIVATE::TVariantSelectedType<typename TRemoveReference<T>::Type, Types...>::Type>, Forward<T>(InValue)) constexpr TVariant(T&& InValue) : TVariant(InPlaceType<typename NAMESPACE_PRIVATE::TVariantSelectedType<typename TRemoveReference<T>::Type, Types...>::Type>, Forward<T>(InValue))
{ } { }
@ -187,7 +187,7 @@ struct TVariant
} }
template <size_t I, typename... ArgTypes> requires (I < AlternativeSize) template <size_t I, typename... ArgTypes> requires (I < AlternativeSize)
&& CConstructible<typename TAlternativeType<I>::Type, ArgTypes...> && CConstructibleFrom<typename TAlternativeType<I>::Type, ArgTypes...>
constexpr typename TAlternativeType<I>::Type& Emplace(ArgTypes&&... Args) constexpr typename TAlternativeType<I>::Type& Emplace(ArgTypes&&... Args)
{ {
Reset(); Reset();
@ -200,7 +200,7 @@ struct TVariant
} }
template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE) template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE)
&& CConstructible<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...> && CConstructibleFrom<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...>
constexpr T& Emplace(ArgTypes&&... Args) constexpr T& Emplace(ArgTypes&&... Args)
{ {
return Emplace<TAlternativeIndex<T>::Value>(Forward<ArgTypes>(Args)...); return Emplace<TAlternativeIndex<T>::Value>(Forward<ArgTypes>(Args)...);
@ -319,7 +319,7 @@ struct TVariant
return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value)); return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value));
} }
constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible<Types> && TIsSwappable<Types>::Value)) constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible<Types> && CSwappable<Types>))
{ {
if (!IsValid() && !InValue.IsValid()) return; if (!IsValid() && !InValue.IsValid()) return;
@ -409,16 +409,22 @@ constexpr bool operator==(const TVariant<Types...>& LHS, FInvalid)
return !LHS.IsValid(); return !LHS.IsValid();
} }
NAMESPACE_PRIVATE_BEGIN
template <typename T > struct TIsTVariant : FFalse { }; template <typename T > struct TIsTVariant : FFalse { };
template <typename... Types> struct TIsTVariant<TVariant<Types...>> : FTrue { }; template <typename... Types> struct TIsTVariant<TVariant<Types...>> : FTrue { };
template <typename VariantType> requires TIsTVariant<typename TRemoveCVRef<VariantType>::Type>::Value NAMESPACE_PRIVATE_END
template <typename T> concept CTVariant = NAMESPACE_PRIVATE::TIsTVariant<T>::Value;
template <typename VariantType> requires CTVariant<typename TRemoveCVRef<VariantType>::Type>
struct TVariantAlternativeSize : TConstant<size_t, VariantType::AlternativeSize> { }; struct TVariantAlternativeSize : TConstant<size_t, VariantType::AlternativeSize> { };
template <size_t I, typename VariantType> requires TIsTVariant<typename TRemoveCVRef<VariantType>::Type>::Value template <size_t I, typename VariantType> requires CTVariant<typename TRemoveCVRef<VariantType>::Type>
struct TVariantAlternativeType { using Type = typename TCopyCV<typename TRemoveReference<VariantType>::Type, typename TRemoveCVRef<VariantType>::Type::template TAlternativeType<I>::Type>::Type; }; struct TVariantAlternativeType { using Type = typename TCopyCV<typename TRemoveReference<VariantType>::Type, typename TRemoveCVRef<VariantType>::Type::template TAlternativeType<I>::Type>::Type; };
template <typename T, typename VariantType> requires TIsTVariant<typename TRemoveCVRef<VariantType>::Type>::Value template <typename T, typename VariantType> requires CTVariant<typename TRemoveCVRef<VariantType>::Type>
struct TVariantAlternativeIndex : VariantType::template TAlternativeIndex<T> { }; struct TVariantAlternativeIndex : VariantType::template TAlternativeIndex<T> { };
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)

View File

@ -1,17 +0,0 @@
#pragma once
#include "CoreTypes.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Testing)
REDCRAFTUTILITY_API void TestConcepts();
NAMESPACE_END(Testing)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -13,32 +13,34 @@ NAMESPACE_MODULE_BEGIN(Utility)
// Assume that all operands of bitwise operations have the same size // Assume that all operands of bitwise operations have the same size
// This type traits is allowed to be specialised. // Specialize these template classes for user-defined types
template <typename T> struct TIsZeroConstructible : TBoolConstant<CDefaultConstructible<T> && (CEnum<T> || CArithmetic<T> || CPointer<T>)> { }; template <typename T> struct TIsZeroConstructible;
// This type traits is allowed to be specialised.
template <typename T, typename U> struct TIsBitwiseConstructible; template <typename T, typename U> struct TIsBitwiseConstructible;
template <typename T, typename U> struct TIsBitwiseRelocatable;
template <typename T> struct TIsBitwiseComparable;
template <typename T, typename U> struct TIsBitwiseConstructible< T, const U> : TIsBitwiseConstructible<T, U> { }; // Normal use of these concepts
template <typename T, typename U> struct TIsBitwiseConstructible< T, volatile U> : TIsBitwiseConstructible<T, U> { }; template <typename T> concept CZeroConstructible = TIsZeroConstructible<T>::Value;
template <typename T, typename U> struct TIsBitwiseConstructible< T, const volatile U> : TIsBitwiseConstructible<T, U> { }; template <typename T, typename U = T> concept CBitwiseConstructible = TIsBitwiseConstructible<T, U>::Value;
template <typename T, typename U> struct TIsBitwiseConstructible<const T, U> : TIsBitwiseConstructible<T, U> { }; template <typename T, typename U = T> concept CBitwiseRelocatable = TIsBitwiseRelocatable<T, U>::Value;
template <typename T, typename U> struct TIsBitwiseConstructible<const T, const U> : TIsBitwiseConstructible<T, U> { }; template <typename T> concept CBitwiseComparable = TIsBitwiseComparable<T>::Value;
template <typename T, typename U> struct TIsBitwiseConstructible<const T, volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<const T, const volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible< volatile T, U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible< volatile T, const U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible< volatile T, volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible< volatile T, const volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<const volatile T, U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<const volatile T, const U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<const volatile T, volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<const volatile T, const volatile U> : TIsBitwiseConstructible<T, U> { };
template <typename T, typename U> struct TIsBitwiseConstructible<T*, U*> : TBoolConstant<CConvertibleTo<U*, T*>> { }; // Default constructible enum, arithmetic and pointer are zero constructible
template <typename T> struct TIsZeroConstructible : TBoolConstant<CDefaultConstructible<T> && (CEnum<T> || CArithmetic<T> || CPointer<T>)> { };
// Constructing a const T is the same as constructing a T
template <typename T> struct TIsZeroConstructible<const T> : TIsZeroConstructible<T> { };
// T can always be bitwise constructed from itself if it is trivially copy constructible
template <typename T, typename U> struct TIsBitwiseConstructible : TBoolConstant<CSameAs<T, U> ? CTriviallyCopyConstructible<T> : false> { }; template <typename T, typename U> struct TIsBitwiseConstructible : TBoolConstant<CSameAs<T, U> ? CTriviallyCopyConstructible<T> : false> { };
// Constructing a const T is the same as constructing a T
template <typename T, typename U> struct TIsBitwiseConstructible<const T, U> : TIsBitwiseConstructible<T, U> { };
// Const pointers can be bitwise constructed from non-const pointers
template <typename T> struct TIsBitwiseConstructible<const T*, T*> : FTrue { };
// Unsigned types can be bitwise converted to their signed equivalents, and vice versa
template <> struct TIsBitwiseConstructible<uint8, int8> : FTrue { }; template <> struct TIsBitwiseConstructible<uint8, int8> : FTrue { };
template <> struct TIsBitwiseConstructible< int8, uint8> : FTrue { }; template <> struct TIsBitwiseConstructible< int8, uint8> : FTrue { };
template <> struct TIsBitwiseConstructible<uint16, int16> : FTrue { }; template <> struct TIsBitwiseConstructible<uint16, int16> : FTrue { };
@ -48,32 +50,19 @@ template <> struct TIsBitwiseConstructible< int32, uint32> : FTrue { };
template <> struct TIsBitwiseConstructible<uint64, int64> : FTrue { }; template <> struct TIsBitwiseConstructible<uint64, int64> : FTrue { };
template <> struct TIsBitwiseConstructible< int64, uint64> : FTrue { }; template <> struct TIsBitwiseConstructible< int64, uint64> : FTrue { };
// It is usually only necessary to specialize TIsBitwiseConstructible and not recommended to specialize TIsBitwiseRelocatable. // WARNING: T is bitwise relocatable from itself by default
template <typename T, typename U> struct TIsBitwiseRelocatable; // T is bitwise relocatable from U, if U is trivially destructible and can be constructed bitwise to T
template <typename T, typename U> struct TIsBitwiseRelocatable : TBoolConstant<CSameAs<T, U> ? true : CTriviallyDestructible<U> && CBitwiseConstructible<T, U>> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< T, const U> : TIsBitwiseRelocatable<T, U> { }; // Constructing a const T is the same as constructing a T
template <typename T, typename U> struct TIsBitwiseRelocatable< T, volatile U> : TIsBitwiseRelocatable<T, U> { }; template <typename T, typename U> struct TIsBitwiseRelocatable<const T, U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< T, const volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const T, U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const T, const U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const T, volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const T, const volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< volatile T, U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< volatile T, const U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< volatile T, volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable< volatile T, const volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const volatile T, U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const volatile T, const U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const volatile T, volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T, typename U> struct TIsBitwiseRelocatable<const volatile T, const volatile U> : TIsBitwiseRelocatable<T, U> { };
template <typename T> struct TIsBitwiseRelocatable<T, T> : TBoolConstant<CObject<T>> { }; // Enum, arithmetic and pointer are zero constructible
template <typename T, typename U> struct TIsBitwiseRelocatable : TBoolConstant<TIsBitwiseConstructible<T, U>::Value && CTriviallyDestructible<U>> { };
// This type traits is allowed to be specialised.
template <typename T> struct TIsBitwiseComparable : TBoolConstant<CEnum<T> || CArithmetic<T> || CPointer<T>> { }; template <typename T> struct TIsBitwiseComparable : TBoolConstant<CEnum<T> || CArithmetic<T> || CPointer<T>> { };
// Constructing a const T is the same as constructing a T
template <typename T> struct TIsBitwiseComparable<const T> : TIsBitwiseComparable<T> { };
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END NAMESPACE_REDCRAFT_END

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "CoreTypes.h" #include "CoreTypes.h"
#include "TypeTraits/HelperClasses.h" #include "TypeTraits/Miscellaneous.h"
#include <type_traits> #include <type_traits>
@ -24,6 +24,31 @@ NAMESPACE_PRIVATE_END
template <typename... Types> struct TCommonType : TConditional<NAMESPACE_PRIVATE::CCommonType<Types...>, NAMESPACE_PRIVATE::TCommonType<Types...>, NAMESPACE_PRIVATE::FNoopStruct>::Type { }; template <typename... Types> struct TCommonType : TConditional<NAMESPACE_PRIVATE::CCommonType<Types...>, NAMESPACE_PRIVATE::TCommonType<Types...>, NAMESPACE_PRIVATE::FNoopStruct>::Type { };
template <typename... Types> struct TCommonReference : TConditional<NAMESPACE_PRIVATE::CCommonReference<Types...>, NAMESPACE_PRIVATE::TCommonReference<Types...>, NAMESPACE_PRIVATE::FNoopStruct>::Type { }; template <typename... Types> struct TCommonReference : TConditional<NAMESPACE_PRIVATE::CCommonReference<Types...>, NAMESPACE_PRIVATE::TCommonReference<Types...>, NAMESPACE_PRIVATE::FNoopStruct>::Type { };
template <typename T, typename U>
concept CCommonReferenceWith =
requires
{
typename TCommonReference<T, U>::Type;
typename TCommonReference<U, T>::Type;
} &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type> &&
CConvertibleTo<T, typename TCommonReference<T, U>::Type>&&
CConvertibleTo<U, typename TCommonReference<T, U>::Type>;
template <typename T, typename U>
concept CCommonWith =
requires
{
typename TCommonType<T, U>::Type;
typename TCommonType<U, T>::Type;
requires CSameAs<typename TCommonType<T, U>::Type, typename TCommonType<U, T>::Type>;
static_cast<TCommonType<T, U>::Type>(DeclVal<T>());
static_cast<TCommonType<T, U>::Type>(DeclVal<U>());
} &&
CCommonReferenceWith<const T&, const U&> &&
CCommonReferenceWith<typename TCommonType<T, U>::Type&, typename TCommonReference<const T&, const U&>::Type> &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type>;
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END NAMESPACE_REDCRAFT_END

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Concepts/Common.h" #include "TypeTraits/Common.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/Miscellaneous.h"
#include "Concepts/BooleanTestable.h" #include "TypeTraits/BooleanTestable.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
@ -11,7 +11,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U> template <typename T, typename U>
concept CWeaklyEqualityComparableWith = concept CWeaklyEqualityComparableWith =
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B) requires(const typename TRemoveReference<T>::Type& A, const typename TRemoveReference<U>::Type& B)
{ {
{ A == B } -> CBooleanTestable; { A == B } -> CBooleanTestable;
{ A != B } -> CBooleanTestable; { A != B } -> CBooleanTestable;
@ -32,7 +32,7 @@ concept CEqualityComparableWith =
template <typename T, typename U> template <typename T, typename U>
concept CPartiallyOrderedWith = concept CPartiallyOrderedWith =
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B) requires(const typename TRemoveReference<T>::Type& A, const typename TRemoveReference<U>::Type& B)
{ {
{ A < B } -> CBooleanTestable; { A < B } -> CBooleanTestable;
{ A > B } -> CBooleanTestable; { A > B } -> CBooleanTestable;

View File

@ -7,12 +7,19 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTInPlaceType : FFalse { }; template <typename T> struct TIsTInPlaceType : FFalse { };
template <typename T> struct TIsTInPlaceType<TInPlaceType<T>> : FTrue { }; template <typename T> struct TIsTInPlaceType<TInPlaceType<T>> : FTrue { };
template <typename T> struct TIsTInPlaceIndex : FFalse { }; template <typename T> struct TIsTInPlaceIndex : FFalse { };
template <size_t I> struct TIsTInPlaceIndex<TInPlaceIndex<I>> : FTrue { }; template <size_t I> struct TIsTInPlaceIndex<TInPlaceIndex<I>> : FTrue { };
NAMESPACE_PRIVATE_END
template <typename T> concept CTInPlaceType = NAMESPACE_PRIVATE::TIsTInPlaceType<T>::Value;
template <typename T> concept CTInPlaceIndex = NAMESPACE_PRIVATE::TIsTInPlaceIndex<T>::Value;
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END NAMESPACE_REDCRAFT_END

View File

@ -51,6 +51,7 @@ template <bool B, typename T = void> struct TEnableIf { using Type =
template <bool B, typename T, typename F> struct TConditional { using Type = NAMESPACE_STD::conditional_t<B, T, F>; }; template <bool B, typename T, typename F> struct TConditional { using Type = NAMESPACE_STD::conditional_t<B, T, F>; };
template <typename T> struct TUnderlyingType { using Type = NAMESPACE_STD::underlying_type_t<T>; }; template <typename T> struct TUnderlyingType { using Type = NAMESPACE_STD::underlying_type_t<T>; };
template <typename... Types> struct TVoid { using Type = void; }; template <typename... Types> struct TVoid { using Type = void; };
template <typename T> struct TIdentity { using Type = T; };
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Concepts/Swappable.h" #include "TypeTraits/Swappable.h"
#include "Concepts/Assignable.h" #include "TypeTraits/Comparable.h"
#include "Concepts/Comparable.h" #include "TypeTraits/CompositeType.h"
#include "TypeTraits/TypeTraits.h" #include "TypeTraits/SupportedOperations.h"
#include "Concepts/Constructible.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
@ -15,18 +14,16 @@ template <typename T>
concept CMovable = concept CMovable =
CObject<T> && CObject<T> &&
CMoveConstructible<T> && CMoveConstructible<T> &&
CAssignableFrom<T&, T> && CMoveAssignable<T> &&
CSwappable<T>; CSwappable<T>;
template <typename T> template <typename T>
concept CCopyable = CMovable<T> && concept CCopyable = CMovable<T> &&
CCopyConstructible<T> && CCopyConstructible<T> &&
CAssignableFrom<T&, T&> && CCopyAssignable<T>;
CAssignableFrom<T&, const T&> &&
CAssignableFrom<T&, const T>;
template <typename T> template <typename T>
concept CSemiregular = CCopyable<T> && CDefaultInitializable<T>; concept CSemiregular = CCopyable<T> && CDefaultConstructible<T>;
template <typename T> template <typename T>
concept CRegular = CSemiregular<T> && CEqualityComparable<T>; concept CRegular = CSemiregular<T> && CEqualityComparable<T>;

View File

@ -37,17 +37,17 @@ template <typename T> concept CVirtualDestructible = CDestructible<T>
//template <typename T> concept CNothrowMoveAssignable; //template <typename T> concept CNothrowMoveAssignable;
//template <typename T> concept CNothrowDestructible; //template <typename T> concept CNothrowDestructible;
template <typename T, typename U> concept CAssignable = NAMESPACE_STD::is_assignable_v<T, U>; template <typename T, typename U> concept CAssignableFrom = NAMESPACE_STD::is_assignable_v<T, U>;
template <typename T, typename U> concept CTriviallyAssignable = CAssignable<T, U> && NAMESPACE_STD::is_trivially_assignable_v<T, U>; template <typename T, typename U> concept CTriviallyAssignableFrom = CAssignableFrom<T, U> && NAMESPACE_STD::is_trivially_assignable_v<T, U>;
//template <typename T, typename U> concept CNothrowAssignable; //template <typename T, typename U> concept CNothrowAssignableFrom;
template <typename T, typename... Args> concept CConstructible = NAMESPACE_STD::is_constructible_v<T, Args...>; template <typename T, typename... Args> concept CConstructibleFrom = NAMESPACE_STD::is_constructible_v<T, Args...>;
template <typename T, typename... Args> concept CTriviallyConstructible = CConstructible<T, Args...> && NAMESPACE_STD::is_trivially_constructible_v<T, Args...>; template <typename T, typename... Args> concept CTriviallyConstructibleFrom = CConstructibleFrom<T, Args...> && NAMESPACE_STD::is_trivially_constructible_v<T, Args...>;
//template <typename T, typename... Args> concept CNothrowConstructible; //template <typename T, typename... Args> concept CNothrowConstructibleFrom;
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)

View File

@ -2,19 +2,17 @@
#include "CoreTypes.h" #include "CoreTypes.h"
#include "Templates/Utility.h" #include "Templates/Utility.h"
#include "TypeTraits/HelperClasses.h" #include "TypeTraits/Common.h"
NAMESPACE_REDCRAFT_BEGIN NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_PRIVATE_BEGIN
template <typename T> template <typename T>
concept CSwappable = requires(T & A, T & B) { Swap(A, B); }; concept CSwappable = requires(T& A, T& B) { Swap(A, B); };
template <typename T, typename U> template <typename T, typename U>
concept CSwappableWith = concept CSwappableWith = CCommonReferenceWith<T, U> &&
requires(T&& A, U&& B) requires(T&& A, U&& B)
{ {
Swap(Forward<T>(A), Forward<T>(A)); Swap(Forward<T>(A), Forward<T>(A));
@ -23,13 +21,8 @@ concept CSwappableWith =
Swap(Forward<U>(B), Forward<T>(A)); Swap(Forward<U>(B), Forward<T>(A));
}; };
NAMESPACE_PRIVATE_END //template <typename T> concept CNothrowSwappable;
//template <typename T, typename U> concept CNothrowSwappableWith;
template <typename T> struct TIsSwappable : TBoolConstant<NAMESPACE_PRIVATE::CSwappable<T>> { };
template <typename T, typename U> struct TIsSwappableWith : TBoolConstant<NAMESPACE_PRIVATE::CSwappableWith<T, U>> { };
//template <typename T> struct TIsNothrowSwappable;
//template <typename T, typename U> struct TIsNothrowSwappableWith;
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)

View File

@ -14,3 +14,5 @@
#include "TypeTraits/InPlaceSpecialization.h" #include "TypeTraits/InPlaceSpecialization.h"
#include "TypeTraits/BitwiseOperations.h" #include "TypeTraits/BitwiseOperations.h"
#include "TypeTraits/BooleanTestable.h" #include "TypeTraits/BooleanTestable.h"
#include "TypeTraits/Object.h"
#include "TypeTraits/Comparable.h"