2022-03-22 03:10:12 +00:00
# pragma once
# include "CoreTypes.h"
# include "Memory/Memory.h"
2022-04-27 14:50:56 +00:00
# include "Memory/Alignment.h"
2022-03-22 03:10:12 +00:00
# include "Templates/Utility.h"
2022-04-22 14:28:44 +00:00
# include "Templates/TypeHash.h"
2022-03-22 03:10:12 +00:00
# include "TypeTraits/TypeTraits.h"
# include "Miscellaneous/TypeInfo.h"
# include "Miscellaneous/AssertionMacros.h"
2022-04-30 15:38:09 +00:00
// NOTE: Disable alignment limit warning
# pragma warning(disable : 4359)
2022-03-22 03:10:12 +00:00
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN ( Redcraft )
NAMESPACE_MODULE_BEGIN ( Utility )
NAMESPACE_PRIVATE_BEGIN
2022-04-30 15:38:09 +00:00
enum class EAnyRepresentation : uint8
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
Trivial , // Trivial
// Inline, // InlineAllocation
Small , // Trivial & Inline
Big , // HeapAllocation
2022-03-22 03:10:12 +00:00
} ;
NAMESPACE_PRIVATE_END
2022-04-30 15:38:09 +00:00
inline constexpr size_t ANY_DEFAULT_INLINE_SIZE = 64 - sizeof ( uintptr ) ;
2022-04-05 05:20:00 +00:00
inline constexpr size_t ANY_DEFAULT_INLINE_ALIGNMENT = 16 ;
2022-03-31 09:36:48 +00:00
2022-04-27 14:50:56 +00:00
template < size_t InlineSize , size_t InlineAlignment = ANY_DEFAULT_INLINE_ALIGNMENT > requires ( Memory : : IsValidAlignment ( InlineAlignment ) )
2022-04-30 15:38:09 +00:00
struct alignas ( InlineAlignment ) TAny
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
constexpr TAny ( ) : TypeInfo ( 0 ) { }
2022-03-22 03:10:12 +00:00
2022-04-03 14:55:17 +00:00
constexpr TAny ( FInvalid ) : TAny ( ) { }
2022-03-22 03:10:12 +00:00
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny ( const TAny & InValue )
2022-04-30 15:38:09 +00:00
: TypeInfo ( InValue . TypeInfo )
2022-03-22 03:10:12 +00:00
{
if ( ! IsValid ( ) ) return ;
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
{
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . CopyConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
HeapAllocation = Memory : : Malloc ( GetTypeInfo ( ) . GetTypeSize ( ) , GetTypeInfo ( ) . GetTypeAlignment ( ) ) ;
GetTypeInfo ( ) . CopyConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
default : check_no_entry ( ) ;
}
2022-03-22 03:10:12 +00:00
}
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny ( TAny & & InValue )
2022-04-30 15:38:09 +00:00
: TypeInfo ( InValue . TypeInfo )
2022-03-22 03:10:12 +00:00
{
if ( ! IsValid ( ) ) return ;
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . MoveConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
HeapAllocation = InValue . HeapAllocation ;
InValue . TypeInfo = 0 ;
break ;
default : check_no_entry ( ) ;
2022-03-22 03:10:12 +00:00
}
}
template < typename T , typename . . . Types > requires TIsObject < typename TDecay < T > : : Type > : : Value
& & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
& & TIsConstructible < typename TDecay < T > : : Type , Types . . . > : : Value
2022-04-05 09:00:33 +00:00
FORCEINLINE explicit TAny ( TInPlaceType < T > , Types & & . . . Args )
2022-03-22 03:10:12 +00:00
{
using SelectedType = typename TDecay < T > : : Type ;
2022-04-03 14:55:17 +00:00
EmplaceImpl < SelectedType > ( Forward < Types > ( Args ) . . . ) ;
2022-03-22 03:10:12 +00:00
}
2022-03-31 09:36:48 +00:00
template < typename T > requires ( ! TIsSame < typename TDecay < T > : : Type , TAny > : : Value ) & & ( ! TIsTInPlaceType < typename TDecay < T > : : Type > : : Value )
2022-03-22 03:10:12 +00:00
& & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
& & TIsConstructible < typename TDecay < T > : : Type , T & & > : : Value
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny ( T & & InValue ) : TAny ( InPlaceType < typename TDecay < T > : : Type > , Forward < T > ( InValue ) )
2022-03-22 03:10:12 +00:00
{ }
2022-04-05 09:00:33 +00:00
FORCEINLINE ~ TAny ( )
2022-03-22 03:10:12 +00:00
{
2022-04-05 09:00:33 +00:00
ResetImpl ( ) ;
2022-03-22 03:10:12 +00:00
}
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny & operator = ( const TAny & InValue )
2022-03-22 03:10:12 +00:00
{
2022-04-03 14:55:17 +00:00
if ( & InValue = = this ) return * this ;
2022-03-22 03:10:12 +00:00
if ( ! InValue . IsValid ( ) )
{
Reset ( ) ;
}
2022-04-05 09:00:33 +00:00
else if ( GetTypeInfo ( ) = = InValue . GetTypeInfo ( ) )
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
{
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
GetTypeInfo ( ) . CopyAssign ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
default : check_no_entry ( ) ;
}
2022-03-22 03:10:12 +00:00
}
else
{
2022-04-05 09:00:33 +00:00
ResetImpl ( ) ;
2022-03-22 03:10:12 +00:00
TypeInfo = InValue . TypeInfo ;
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
{
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . CopyConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
HeapAllocation = Memory : : Malloc ( GetTypeInfo ( ) . GetTypeSize ( ) , GetTypeInfo ( ) . GetTypeAlignment ( ) ) ;
GetTypeInfo ( ) . CopyConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
default : check_no_entry ( ) ;
}
2022-03-22 03:10:12 +00:00
}
return * this ;
}
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny & operator = ( TAny & & InValue )
2022-03-22 03:10:12 +00:00
{
2022-04-03 14:55:17 +00:00
if ( & InValue = = this ) return * this ;
2022-03-22 03:10:12 +00:00
if ( ! InValue . IsValid ( ) )
{
Reset ( ) ;
}
2022-04-05 09:00:33 +00:00
else if ( GetTypeInfo ( ) = = InValue . GetTypeInfo ( ) )
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . MoveAssign ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
ResetImpl ( ) ;
HeapAllocation = InValue . HeapAllocation ;
InValue . TypeInfo = 0 ;
break ;
default : check_no_entry ( ) ;
2022-03-22 03:10:12 +00:00
}
}
else
{
2022-04-05 09:00:33 +00:00
ResetImpl ( ) ;
2022-03-22 03:10:12 +00:00
TypeInfo = InValue . TypeInfo ;
2022-04-30 15:38:09 +00:00
switch ( GetRepresentation ( ) )
{
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
Memory : : Memcpy ( InlineAllocation , InValue . InlineAllocation ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . MoveConstruct ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
HeapAllocation = InValue . HeapAllocation ;
InValue . TypeInfo = 0 ;
break ;
default : check_no_entry ( ) ;
}
2022-03-22 03:10:12 +00:00
}
return * this ;
}
2022-03-31 09:36:48 +00:00
template < typename T > requires ( ! TIsSame < typename TDecay < T > : : Type , TAny > : : Value ) & & ( ! TIsTInPlaceType < typename TDecay < T > : : Type > : : Value )
2022-03-22 03:10:12 +00:00
& & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
& & TIsConstructible < typename TDecay < T > : : Type , T & & > : : Value
2022-04-05 09:00:33 +00:00
FORCEINLINE TAny & operator = ( T & & InValue )
2022-03-22 03:10:12 +00:00
{
using SelectedType = typename TDecay < T > : : Type ;
2022-04-05 09:00:33 +00:00
if ( HoldsAlternative < SelectedType > ( ) )
2022-03-22 03:10:12 +00:00
{
2022-04-30 15:38:09 +00:00
GetValue < SelectedType > ( ) = Forward < T > ( InValue ) ;
2022-03-22 03:10:12 +00:00
}
else
{
2022-04-30 15:38:09 +00:00
ResetImpl ( ) ;
2022-04-03 14:55:17 +00:00
EmplaceImpl < SelectedType > ( Forward < T > ( InValue ) ) ;
2022-03-22 03:10:12 +00:00
}
return * this ;
}
template < typename T , typename . . . Types > requires TIsObject < typename TDecay < T > : : Type > : : Value
& & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
& & TIsConstructible < typename TDecay < T > : : Type , T & & > : : Value
2022-04-05 09:00:33 +00:00
FORCEINLINE typename TDecay < T > : : Type & Emplace ( Types & & . . . Args )
2022-03-22 03:10:12 +00:00
{
2022-04-05 09:00:33 +00:00
ResetImpl ( ) ;
2022-03-22 03:10:12 +00:00
using SelectedType = typename TDecay < T > : : Type ;
2022-04-03 14:55:17 +00:00
EmplaceImpl < SelectedType > ( Forward < Types > ( Args ) . . . ) ;
2022-03-22 03:10:12 +00:00
return GetValue < SelectedType > ( ) ;
}
2022-04-30 15:38:09 +00:00
constexpr const FTypeInfo & GetTypeInfo ( ) const { return IsValid ( ) ? * reinterpret_cast < FTypeInfo * > ( TypeInfo & ~ RepresentationMask ) : Typeid ( void ) ; }
2022-04-05 09:00:33 +00:00
2022-04-30 15:38:09 +00:00
constexpr bool IsValid ( ) const { return TypeInfo ! = 0 ; }
constexpr explicit operator bool ( ) const { return TypeInfo ! = 0 ; }
2022-03-22 03:10:12 +00:00
2022-04-05 09:00:33 +00:00
template < typename T > constexpr bool HoldsAlternative ( ) const { return IsValid ( ) ? GetTypeInfo ( ) = = Typeid ( T ) : false ; }
2022-03-22 03:10:12 +00:00
2022-03-23 09:49:30 +00:00
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
2022-04-30 15:38:09 +00:00
constexpr T & GetValue ( ) & { checkf ( HoldsAlternative < T > ( ) , TEXT ( " It is an error to call GetValue() on an wrong TAny. Please either check HoldsAlternative() or use Get(DefaultValue) instead. " ) ) ; return * reinterpret_cast < T * > ( GetAllocation ( ) ) ; }
2022-03-22 03:10:12 +00:00
2022-03-23 09:49:30 +00:00
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
2022-04-30 15:38:09 +00:00
constexpr T & & GetValue ( ) & & { checkf ( HoldsAlternative < T > ( ) , TEXT ( " It is an error to call GetValue() on an wrong TAny. Please either check HoldsAlternative() or use Get(DefaultValue) instead. " ) ) ; return MoveTemp ( * reinterpret_cast < T * > ( GetAllocation ( ) ) ) ; }
2022-03-23 09:49:30 +00:00
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
2022-04-30 15:38:09 +00:00
constexpr const T & GetValue ( ) const & { checkf ( HoldsAlternative < T > ( ) , TEXT ( " It is an error to call GetValue() on an wrong TAny. Please either check HoldsAlternative() or use Get(DefaultValue) instead. " ) ) ; return * reinterpret_cast < const T * > ( GetAllocation ( ) ) ; }
2022-03-23 09:49:30 +00:00
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
2022-04-30 15:38:09 +00:00
constexpr const T & & GetValue ( ) const & & { checkf ( HoldsAlternative < T > ( ) , TEXT ( " It is an error to call GetValue() on an wrong TAny. Please either check HoldsAlternative() or use Get(DefaultValue) instead. " ) ) ; return MoveTemp ( * reinterpret_cast < const T * > ( GetAllocation ( ) ) ) ; }
2022-03-23 09:49:30 +00:00
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
constexpr T & Get ( T & DefaultValue ) & { return HoldsAlternative < T > ( ) ? GetValue < T > ( ) : DefaultValue ; }
template < typename T > requires TIsSame < T , typename TDecay < T > : : Type > : : Value & & TIsObject < typename TDecay < T > : : Type > : : Value & & ( ! TIsArray < typename TDecay < T > : : Type > : : Value ) & & TIsDestructible < typename TDecay < T > : : Type > : : Value
constexpr const T & Get ( const T & DefaultValue ) const & { return HoldsAlternative < T > ( ) ? GetValue < T > ( ) : DefaultValue ; }
2022-03-22 03:10:12 +00:00
2022-04-05 09:00:33 +00:00
FORCEINLINE void Reset ( )
2022-03-22 03:10:12 +00:00
{
2022-04-05 09:00:33 +00:00
ResetImpl ( ) ;
2022-04-30 15:38:09 +00:00
TypeInfo = 0 ;
2022-03-22 03:10:12 +00:00
}
2022-04-30 15:38:09 +00:00
FORCEINLINE size_t GetTypeHash ( ) const
{
if ( ! IsValid ( ) ) return 20090007 ;
return HashCombine ( GetTypeInfo ( ) . GetTypeHash ( ) , GetTypeInfo ( ) . HashItem ( GetAllocation ( ) ) ) ;
}
FORCEINLINE void Swap ( TAny & InValue )
{
if ( ! IsValid ( ) & & ! InValue . IsValid ( ) ) return ;
if ( IsValid ( ) & & ! InValue . IsValid ( ) )
{
InValue = MoveTemp ( * this ) ;
Reset ( ) ;
return ;
}
if ( InValue . IsValid ( ) & & ! IsValid ( ) )
{
* this = MoveTemp ( InValue ) ;
InValue . Reset ( ) ;
return ;
}
if ( GetTypeInfo ( ) = = InValue . GetTypeInfo ( ) )
{
GetTypeInfo ( ) . SwapItem ( GetAllocation ( ) , InValue . GetAllocation ( ) ) ;
return ;
}
TAny Temp = MoveTemp ( * this ) ;
* this = MoveTemp ( InValue ) ;
InValue = MoveTemp ( Temp ) ;
}
2022-04-14 14:41:22 +00:00
2022-03-22 03:10:12 +00:00
private :
2022-04-30 15:38:09 +00:00
static constexpr uintptr_t RepresentationMask = 3 ;
2022-03-22 03:10:12 +00:00
union
{
2022-04-30 15:38:09 +00:00
TAlignedStorage < InlineSize , 1 > : : Type InlineAllocation ;
void * HeapAllocation ;
2022-03-22 03:10:12 +00:00
} ;
2022-04-30 15:38:09 +00:00
uintptr TypeInfo ;
constexpr NAMESPACE_PRIVATE : : EAnyRepresentation GetRepresentation ( ) const { return static_cast < NAMESPACE_PRIVATE : : EAnyRepresentation > ( TypeInfo & RepresentationMask ) ; }
constexpr void * GetAllocation ( ) { return GetRepresentation ( ) = = NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial | | GetRepresentation ( ) = = NAMESPACE_PRIVATE : : EAnyRepresentation : : Small ? & InlineAllocation : HeapAllocation ; }
constexpr const void * GetAllocation ( ) const { return GetRepresentation ( ) = = NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial | | GetRepresentation ( ) = = NAMESPACE_PRIVATE : : EAnyRepresentation : : Small ? & InlineAllocation : HeapAllocation ; }
2022-04-03 14:55:17 +00:00
template < typename SelectedType , typename . . . Types >
2022-04-05 05:20:00 +00:00
FORCEINLINE void EmplaceImpl ( Types & & . . . Args )
2022-04-03 14:55:17 +00:00
{
2022-04-30 15:38:09 +00:00
TypeInfo = reinterpret_cast < uintptr > ( & Typeid ( SelectedType ) ) ;
2022-04-03 14:55:17 +00:00
2022-04-30 15:38:09 +00:00
constexpr bool bIsInlineStorable = sizeof ( SelectedType ) < = InlineSize & & alignof ( SelectedType ) < = InlineAlignment ;
constexpr bool bIsTriviallyStorable = bIsInlineStorable & & TIsTrivial < SelectedType > : : Value & & TIsTriviallyCopyable < SelectedType > : : Value ;
if constexpr ( bIsTriviallyStorable )
2022-04-03 14:55:17 +00:00
{
2022-04-30 15:38:09 +00:00
new ( & InlineAllocation ) SelectedType ( Forward < Types > ( Args ) . . . ) ;
TypeInfo | = static_cast < uintptr > ( NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial ) ;
2022-04-03 14:55:17 +00:00
}
2022-04-30 15:38:09 +00:00
else if constexpr ( bIsInlineStorable )
2022-04-03 14:55:17 +00:00
{
2022-04-30 15:38:09 +00:00
new ( & InlineAllocation ) SelectedType ( Forward < Types > ( Args ) . . . ) ;
TypeInfo | = static_cast < uintptr > ( NAMESPACE_PRIVATE : : EAnyRepresentation : : Small ) ;
2022-04-03 14:55:17 +00:00
}
else
{
2022-04-30 15:38:09 +00:00
HeapAllocation = new SelectedType ( Forward < Types > ( Args ) . . . ) ;
TypeInfo | = static_cast < uintptr > ( NAMESPACE_PRIVATE : : EAnyRepresentation : : Big ) ;
2022-04-03 14:55:17 +00:00
}
}
2022-04-05 09:00:33 +00:00
FORCEINLINE void ResetImpl ( )
{
2022-04-30 15:38:09 +00:00
if ( ! IsValid ( ) ) return ;
switch ( GetRepresentation ( ) )
{
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Trivial :
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Small :
GetTypeInfo ( ) . Destroy ( GetAllocation ( ) ) ;
break ;
case NAMESPACE_PRIVATE : : EAnyRepresentation : : Big :
GetTypeInfo ( ) . Destroy ( GetAllocation ( ) ) ;
Memory : : Free ( HeapAllocation ) ;
break ;
default : check_no_entry ( ) ;
}
}
friend FORCEINLINE bool operator = = ( const TAny & LHS , const TAny & RHS )
{
if ( LHS . GetTypeInfo ( ) ! = RHS . GetTypeInfo ( ) ) return false ;
if ( LHS . IsValid ( ) = = false ) return true ;
return LHS . GetTypeInfo ( ) . EqualityCompare ( LHS . GetAllocation ( ) , RHS . GetAllocation ( ) ) ;
2022-04-05 09:00:33 +00:00
}
2022-04-30 15:38:09 +00:00
friend FORCEINLINE partial_ordering operator < = > ( const TAny & LHS , const TAny & RHS )
{
if ( LHS . GetTypeInfo ( ) ! = RHS . GetTypeInfo ( ) ) return partial_ordering : : unordered ;
if ( LHS . IsValid ( ) = = false ) return partial_ordering : : equivalent ;
return LHS . GetTypeInfo ( ) . SynthThreeWayCompare ( LHS . GetAllocation ( ) , RHS . GetAllocation ( ) ) ; ;
}
2022-04-22 14:28:44 +00:00
2022-03-22 03:10:12 +00:00
} ;
template < typename T , size_t InlineSize , size_t InlineAlignment >
constexpr bool operator = = ( const TAny < InlineSize , InlineAlignment > & LHS , const T & RHS )
{
return LHS . template HoldsAlternative < T > ( ) ? LHS . template GetValue < T > ( ) = = RHS : false ;
}
template < size_t InlineSize , size_t InlineAlignment >
constexpr bool operator = = ( const TAny < InlineSize , InlineAlignment > & LHS , FInvalid )
{
return ! LHS . IsValid ( ) ;
}
2022-03-31 09:36:48 +00:00
template < typename T > struct TIsTAny : FFalse { } ;
template < size_t InlineSize , size_t InlineAlignment > struct TIsTAny < TAny < InlineSize , InlineAlignment > > : FTrue { } ;
using FAny = TAny < ANY_DEFAULT_INLINE_SIZE > ;
2022-03-22 03:10:12 +00:00
static_assert ( sizeof ( FAny ) = = 64 , " The byte size of FAny is unexpected " ) ;
NAMESPACE_MODULE_END ( Utility )
NAMESPACE_MODULE_END ( Redcraft )
NAMESPACE_REDCRAFT_END