?? untemplate.h
字號:
/*=============================================================================
UnTemplate.h: Unreal templates.
Copyright 1997-1999 Epic Games, Inc. All Rights Reserved.
Revision history:
* Created by Tim Sweeney
=============================================================================*/
/*-----------------------------------------------------------------------------
Type information.
-----------------------------------------------------------------------------*/
//
// Type information for initialization.
//
template <class T> struct TTypeInfoBase
{
typedef const T& ConstInitType;
static UBOOL NeedsDestructor() {return 1;}
};
template <class T> struct TTypeInfo : public TTypeInfoBase<T>
{
};
template<> struct TTypeInfo<FString> : public TTypeInfoBase<T>
{
typedef const TCHAR* ConstInitType;
};
template<> struct TTypeInfo<BYTE> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<SBYTE> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<ANSICHAR> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<INT> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<DWORD> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<_WORD> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<SWORD> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<QWORD> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
template<> struct TTypeInfo<SQWORD> : public TTypeInfoBase<T>
{
static UBOOL NeedsDestructor() {return 0;}
};
/*-----------------------------------------------------------------------------
Standard templates.
-----------------------------------------------------------------------------*/
template< class T > inline T Abs( const T A )
{
return (A>=(T)0) ? A : -A;
}
template< class T > inline T Sgn( const T A )
{
return (A>0) ? 1 : ((A<0) ? -1 : 0);
}
template< class T > inline T Max( const T A, const T B )
{
return (A>=B) ? A : B;
}
template< class T > inline T Min( const T A, const T B )
{
return (A<=B) ? A : B;
}
template< class T > inline T Square( const T A )
{
return A*A;
}
template< class T > inline T Clamp( const T X, const T Min, const T Max )
{
return X<Min ? Min : X<Max ? X : Max;
}
template< class T > inline T Align( const T Ptr, INT Alignment )
{
return (T)(((DWORD)Ptr + Alignment - 1) & ~(Alignment-1));
}
template< class T > inline void Exchange( T& A, T& B )
{
const T Temp = A;
A = B;
B = Temp;
}
template< class T > T Lerp( T& A, T& B, FLOAT Alpha )
{
return A + Alpha * (B-A);
}
inline DWORD GetTypeHash( const BYTE A )
{
return A;
}
inline DWORD GetTypeHash( const SBYTE A )
{
return A;
}
inline DWORD GetTypeHash( const _WORD A )
{
return A;
}
inline DWORD GetTypeHash( const SWORD A )
{
return A;
}
inline DWORD GetTypeHash( const INT A )
{
return A;
}
inline DWORD GetTypeHash( const DWORD A )
{
return A;
}
inline DWORD GetTypeHash( const QWORD A )
{
return (DWORD)A+((DWORD)(A>>32) * 23);
}
inline DWORD GetTypeHash( const SQWORD A )
{
return (DWORD)A+((DWORD)(A>>32) * 23);
}
inline DWORD GetTypeHash( const TCHAR* S )
{
return appStrihash(S);
}
#define ExchangeB(A,B) {UBOOL T=A; A=B; B=T;}
/*----------------------------------------------------------------------------
Standard macros.
----------------------------------------------------------------------------*/
// Number of elements in an array.
#define ARRAY_COUNT( array ) \
( sizeof(array) / sizeof((array)[0]) )
// Offset of a struct member.
#define STRUCT_OFFSET( struc, member ) \
( (INT)&((struc*)NULL)->member )
/*-----------------------------------------------------------------------------
Allocators.
-----------------------------------------------------------------------------*/
template <class T> class TAllocator
{};
/*-----------------------------------------------------------------------------
Dynamic array template.
-----------------------------------------------------------------------------*/
//
// Base dynamic array.
//
class CORE_API FArray
{
public:
void* GetData()
{
return Data;
}
const void* GetData() const
{
return Data;
}
UBOOL IsValidIndex( INT i ) const
{
return i>=0 && i<ArrayNum;
}
INT Num() const
{
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
return ArrayNum;
}
void Insert( INT Index, INT Count, INT ElementSize )
{
guardSlow(FArray::Insert);
checkSlow(Count>=0);
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
checkSlow(Index>=0);
checkSlow(Index<=ArrayNum);
INT OldNum = ArrayNum;
if( (ArrayNum+=Count)>ArrayMax )
{
ArrayMax = ArrayNum + 3*ArrayNum/8 + 32;
Realloc( ElementSize );
}
appMemmove
(
(BYTE*)Data + (Index+Count )*ElementSize,
(BYTE*)Data + (Index )*ElementSize,
(OldNum-Index)*ElementSize
);
unguardSlow;
}
INT Add( INT Count, INT ElementSize )
{
guardSlow(FArray::Add);
checkSlow(Count>=0);
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
INT Index = ArrayNum;
if( (ArrayNum+=Count)>ArrayMax )
{
ArrayMax = ArrayNum + 3*ArrayNum/8 + 32;
Realloc( ElementSize );
}
return Index;
unguardSlow;
}
INT AddZeroed( INT ElementSize, INT n=1 )
{
guardSlow(FArray::AddZeroed);
INT Index = Add( n, ElementSize );
appMemzero( (BYTE*)Data+Index*ElementSize, n*ElementSize );
return Index;
unguardSlow;
}
void Shrink( INT ElementSize )
{
guardSlow(FArray::Shrink);
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
if( ArrayMax != ArrayNum )
{
ArrayMax = ArrayNum;
Realloc( ElementSize );
}
unguardSlow;
}
void Empty( INT ElementSize, INT Slack=0 )
{
guardSlow(FArray::Empty);
ArrayNum = 0;
ArrayMax = Slack;
Realloc( ElementSize );
unguardSlow;
}
FArray()
: ArrayNum( 0 )
, ArrayMax( 0 )
, Data ( NULL )
{}
FArray( ENoInit )
{}
~FArray()
{
guardSlow(FArray::~FArray);
if( Data )
appFree( Data );
Data = NULL;
ArrayNum = ArrayMax = 0;
unguardSlow;
}
void CountBytes( FArchive& Ar, INT ElementSize )
{
guardSlow(FArray::CountBytes);
Ar.CountBytes( ArrayNum*ElementSize, ArrayMax*ElementSize );
unguardSlow;
}
void Remove( INT Index, INT Count, INT ElementSize );
protected:
void Realloc( INT ElementSize );
FArray( INT InNum, INT ElementSize )
: ArrayNum( InNum )
, ArrayMax( InNum )
, Data ( NULL )
{
Realloc( ElementSize );
}
void* Data;
INT ArrayNum;
INT ArrayMax;
};
//
// Templated dynamic array.
//
template< class T > class TArray : public FArray
{
public:
typedef T ElementType;
TArray()
: FArray()
{}
TArray( INT InNum )
: FArray( InNum, sizeof(T) )
{}
TArray( const TArray& Other )
: FArray( Other.ArrayNum, sizeof(T) )
{
guardSlow(TArray::copyctor);
ArrayNum=0;
for( INT i=0; i<Other.ArrayNum; i++ )
new(*this)T(Other(i));
unguardSlow;
}
TArray( ENoInit )
: FArray( E_NoInit )
{}
~TArray()
{
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
Remove( 0, ArrayNum );
}
T& operator()( INT i )
{
guardSlow(TArray::operator());
checkSlow(i>=0);
checkSlow(i<=ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((T*)Data)[i];
unguardSlow;
}
const T& operator()( INT i ) const
{
guardSlow(TArray::operator());
checkSlow(i>=0);
checkSlow(i<=ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((T*)Data)[i];
unguardSlow;
}
T Pop()
{
guardSlow(TArray::Pop);
check(ArrayNum>0);
checkSlow(ArrayMax>=ArrayNum);
T Result = ((T*)Data)[ArrayNum-1];
Remove( ArrayNum-1 );
return Result;
unguardSlow;
}
T& Last()
{
guardSlow(TArray::Last);
check(ArrayNum>0);
checkSlow(ArrayMax>=ArrayNum);
return ((T*)Data)[ArrayNum-1];
unguardSlow;
}
const T& Last() const
{
guardSlow(TArray::Last);
checkSlow(ArrayNum>0);
checkSlow(ArrayMax>=ArrayNum);
return ((T*)Data)[ArrayNum-1];
unguardSlow;
}
void Shrink()
{
guardSlow(TArray::Shrink);
FArray::Shrink( sizeof(T) );
unguardSlow;
}
UBOOL FindItem( const T& Item, INT& Index ) const
{
guardSlow(TArray::FindItem);
for( Index=0; Index<ArrayNum; Index++ )
if( (*this)(Index)==Item )
return 1;
return 0;
unguardSlow;
}
INT FindItemIndex( const T& Item ) const
{
guardSlow(TArray::FindItemIndex);
for( INT Index=0; Index<ArrayNum; Index++ )
if( (*this)(Index)==Item )
return Index;
return INDEX_NONE;
unguardSlow;
}
friend FArchive& operator<<( FArchive& Ar, TArray& A )
{
guard(TArray<<);
A.CountBytes( Ar );
if( sizeof(T)==1 )
{
// Serialize simple bytes which require no construction or destruction.
Ar << AR_INDEX(A.ArrayNum);
if( Ar.IsLoading() )
{
A.ArrayMax = A.ArrayNum;
A.Realloc( sizeof(T) );
}
Ar.Serialize( &A(0), A.Num() );
}
else if( Ar.IsLoading() )
{
// Load array.
INT NewNum;
Ar << AR_INDEX(NewNum);
A.Empty( NewNum );
for( INT i=0; i<NewNum; i++ )
Ar << *new(A)T;
}
else
{
// Save array.
Ar << AR_INDEX(A.ArrayNum);
for( INT i=0; i<A.ArrayNum; i++ )
Ar << A( i );
}
return Ar;
unguard;
}
void CountBytes( FArchive& Ar )
{
guardSlow(TArray::CountBytes);
FArray::CountBytes( Ar, sizeof(T) );
unguardSlow;
}
// Add, Insert, Remove, Empty interface.
INT Add( INT n=1 )
{
guardSlow(TArray::Add);
return FArray::Add( n, sizeof(T) );
unguardSlow;
}
void Insert( INT Index, INT Count=1 )
{
guardSlow(TTransArray::InsertZeroed);
FArray::Insert( Index, Count, sizeof(T) );
unguardSlow;
}
void Remove( INT Index, INT Count=1 )
{
guardSlow(TArray::Remove);
check(Index>=0);
check(Index<=ArrayNum);
check(Index+Count<=ArrayNum);
if( TTypeInfo<T>::NeedsDestructor() )
for( INT i=Index; i<Index+Count; i++ )
(&(*this)(i))->~T();
FArray::Remove( Index, Count, sizeof(T) );
unguardSlow;
}
void Empty( INT Slack=0 )
{
guardSlow(TArray::Empty);
if( TTypeInfo<T>::NeedsDestructor() )
for( INT i=0; i<ArrayNum; i++ )
(&(*this)(i))->~T();
FArray::Empty( sizeof(T), Slack );
unguardSlow;
}
// Functions dependent on Add, Remove.
TArray& operator=( const TArray& Other )
{
guardSlow(TArray::operator=);
if( this != &Other )
{
Empty( Other.ArrayNum );
for( INT i=0; i<Other.ArrayNum; i++ )
new( *this )T( Other(i) );
}
return *this;
unguardSlow;
}
INT AddItem( const T& Item )
{
guardSlow(TArray::AddItem);
INT Index=Add();
(*this)(Index)=Item;
return Index;
unguardSlow;
}
INT AddZeroed( INT n=1 )
{
guardSlow(TArray::AddZeroed);
return FArray::AddZeroed( sizeof(T), n );
unguardSlow;
}
INT AddUniqueItem( const T& Item )
{
guardSlow(TArray::AddUniqueItem);
for( INT Index=0; Index<ArrayNum; Index++ )
if( (*this)(Index)==Item )
return Index;
return AddItem( Item );
unguardSlow;
}
INT RemoveItem( const T& Item )
{
guardSlow(TArray::RemoveItem);
INT OriginalNum=ArrayNum;
for( INT Index=0; Index<ArrayNum; Index++ )
if( (*this)(Index)==Item )
Remove( Index-- );
return OriginalNum - ArrayNum;
unguardSlow;
}
// Iterator.
class TIterator
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -