?? untemplate.h
字號(hào):
}
INT InStr( const FString& SubStr ) const
{
TCHAR* Tmp = appStrstr(**this,*SubStr);
return Tmp ? (Tmp-**this) : -1;
}
INT InStrRight( const TCHAR* SubStr ) const
{
for( INT i=Len()-1; i>=0; i-- )
{
for( INT j=0; SubStr[j]; j++ )
if( (*this)(i+j)!=SubStr[j] )
break;
if( !SubStr[j] )
return i;
}
return -1;
}
INT InStrRight( const FString& SubStr ) const
{
return InStrRight( *SubStr );
}
FString Caps() const
{
FString New( **this );
for( INT i=0; i<ArrayNum; i++ )
New(i) = appToUpper(New(i));
return New;
}
FString Locs() const
{
FString New( **this );
for( INT i=0; i<ArrayNum; i++ )
New(i) = appToLower(New(i));
return New;
}
FString LeftPad( INT ChCount );
FString RightPad( INT ChCount );
static FString Printf( const TCHAR* Fmt, ... );
static FString Chr( TCHAR Ch );
CORE_API friend FArchive& operator<<( FArchive& Ar, FString& S );
friend struct FStringNoInit;
private:
FString( INT InCount, const TCHAR* InSrc )
: TArray<TCHAR>( InCount+1 )
{
appStrncpy( &(*this)(0), InSrc, InCount+1 );
}
};
struct CORE_API FStringNoInit : public FString
{
FStringNoInit()
: FString( E_NoInit )
{}
FStringNoInit& operator=( const TCHAR* Other )
{
if( &(*this)(0)!=Other )
{
ArrayNum = ArrayMax = *Other ? appStrlen(Other)+1 : 0;
Realloc( sizeof(TCHAR) );
if( ArrayNum )
appMemcpy( &(*this)(0), Other, ArrayNum*sizeof(TCHAR) );
}
return *this;
}
FStringNoInit& operator=( const FString& Other )
{
if( this != &Other )
{
ArrayNum = ArrayMax = Other.Num();
Realloc( sizeof(TCHAR) );
if( ArrayNum )
appMemcpy( &(*this)(0), *Other, ArrayNum*sizeof(TCHAR) );
}
return *this;
}
};
inline DWORD GetTypeHash( const FString& S )
{
return appStrihash(*S);
}
//
// String exchanger.
//
inline void ExchangeString( FString& A, FString& B )
{
guardSlow(ExchangeTArray);
appMemswap( &A, &B, sizeof(FString) );
unguardSlow;
}
/*----------------------------------------------------------------------------
Special archivers.
----------------------------------------------------------------------------*/
//
// String output device.
//
class FStringOutputDevice : public FString, public FOutputDevice
{
public:
FStringOutputDevice( const TCHAR* InStr=TEXT("") )
: FString( InStr )
{}
void Serialize( const TCHAR* Data, EName Event )
{
*this += (TCHAR*)Data;
}
};
//
// Buffer writer.
//
class FBufferWriter : public FArchive
{
public:
FBufferWriter( TArray<BYTE>& InBytes )
: Bytes( InBytes )
, Pos( 0 )
{
ArIsSaving = 1;
}
void Serialize( void* InData, INT Length )
{
if( Pos+Length>Bytes.Num() )
Bytes.Add( Pos+Length-Bytes.Num() );
appMemcpy( &Bytes(Pos), InData, Length );
Pos += Length;
}
INT Tell()
{
return Pos;
}
void Seek( INT InPos )
{
Pos = InPos;
}
INT TotalSize()
{
return Bytes.Num();
}
private:
TArray<BYTE>& Bytes;
INT Pos;
};
//
// Buffer archiver.
//
class FBufferArchive : public FBufferWriter, public TArray<BYTE>
{
public:
FBufferArchive()
: FBufferWriter( (TArray<BYTE>&)*this )
{}
};
//
// Buffer reader.
//
class CORE_API FBufferReader : public FArchive
{
public:
FBufferReader( const TArray<BYTE>& InBytes )
: Bytes ( InBytes )
, Pos ( 0 )
{
ArIsLoading = ArIsTrans = 1;
}
void Serialize( void* Data, INT Num )
{
check(Pos>=0);
check(Pos+Num<=Bytes.Num());
appMemcpy( Data, &Bytes(Pos), Num );
Pos += Num;
}
INT Tell()
{
return Pos;
}
INT TotalSize()
{
return Bytes.Num();
}
void Seek( INT InPos )
{
check(InPos>=0);
check(InPos<=Bytes.Num());
Pos = InPos;
}
UBOOL AtEnd()
{
return Pos>=Bytes.Num();
}
private:
const TArray<BYTE>& Bytes;
INT Pos;
};
/*----------------------------------------------------------------------------
TMap.
----------------------------------------------------------------------------*/
//
// Maps unique keys to values.
//
template< class TK, class TI > class TMap
{
private:
class TPair
{
public:
INT HashNext;
TK Key;
TI Value;
TPair( TTypeInfo<TK>::ConstInitType InKey, TTypeInfo<TI>::ConstInitType InValue )
: Key( InKey ), Value( InValue )
{}
TPair()
{}
friend FArchive& operator<<( FArchive& Ar, TPair& F )
{
guardSlow(TMap::TPair<<);
return Ar << F.Key << F.Value;
unguardSlow;
}
};
void Rehash()
{
guardSlow(TMap::Rehash);
checkSlow(!(HashCount&(HashCount-1)));
checkSlow(HashCount>=8);
INT* NewHash = new(TEXT("HashMapHash"))INT[HashCount];
{for( INT i=0; i<HashCount; i++ )
{
NewHash[i] = INDEX_NONE;
}}
{for( INT i=0; i<Pairs.Num(); i++ )
{
TPair& Pair = Pairs(i);
INT iHash = (GetTypeHash(Pair.Key) & (HashCount-1));
Pair.HashNext = NewHash[iHash];
NewHash[iHash] = i;
}}
if( Hash )
delete Hash;
Hash = NewHash;
unguardSlow;
}
void Relax()
{
guardSlow(TMap::Relax);
while( HashCount>Pairs.Num()*2+8 )
HashCount /= 2;
Rehash();
unguardSlow;
}
TArray<TPair> Pairs;
INT* Hash;
INT HashCount;
public:
TMap()
: Hash( NULL )
, HashCount( 8 )
{
guardSlow(TMap::TMap);
Rehash();
unguardSlow;
}
TMap( const TMap& Other )
: Pairs( Other.Pairs )
, HashCount( Other.HashCount )
, Hash( NULL )
{
guardSlow(TMap::TMap copy);
Rehash();
unguardSlow;
}
~TMap()
{
guardSlow(TMap::~TMap);
if( Hash )
delete Hash;
Hash = NULL;
HashCount = 0;
unguardSlow;
}
TMap& operator=( const TMap& Other )
{
guardSlow(TMap::operator=);
Pairs = Other.Pairs;
HashCount = Other.HashCount;
Rehash();
return *this;
unguardSlow;
}
void Empty()
{
guardSlow(TMap::Empty);
checkSlow(!(HashCount&(HashCount-1)));
Pairs.Empty();
HashCount = 8;
Rehash();
unguardSlow;
}
TI& Add( TTypeInfo<TK>::ConstInitType InKey, TTypeInfo<TI>::ConstInitType InValue )
{
guardSlow(TMap::Add);
TPair& Pair = *new(Pairs)TPair( InKey, InValue );
INT iHash = (GetTypeHash(Pair.Key) & (HashCount-1));
Pair.HashNext = Hash[iHash];
Hash[iHash] = Pairs.Num()-1;
if( HashCount*2+8 < Pairs.Num() )
{
HashCount *= 2;
Rehash();
}
return Pair.Value;
unguardSlow;
}
TI& AddUnique( TTypeInfo<TK>::ConstInitType InKey, TTypeInfo<TI>::ConstInitType InValue )
{
for( INT i=Hash[(GetTypeHash(InKey) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==InKey && Pairs(i).Value==InValue )
return Pairs(i).Value;
return Add( InKey, InValue );
}
TI& Set( TTypeInfo<TK>::ConstInitType InKey, TTypeInfo<TI>::ConstInitType InValue )
{
guardSlow(TMap::Set);
for( INT i=Hash[(GetTypeHash(InKey) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==InKey )
{Pairs(i).Value=InValue; return Pairs(i).Value;}
return Add( InKey, InValue );
unguardSlow;
}
INT Remove( TTypeInfo<TK>::ConstInitType InKey )
{
guardSlow(TMap::Remove);
INT Count=0;
for( INT i=Pairs.Num()-1; i>=0; i-- )
if( Pairs(i).Key==InKey )
{Pairs.Remove(i); Count++;}
if( Count )
Relax();
return Count;
unguardSlow;
}
INT RemovePair( TTypeInfo<TK>::ConstInitType InKey, TTypeInfo<TI>::ConstInitType InValue )
{
guardSlow(TMap::Remove);
INT Count=0;
for( INT i=Pairs.Num()-1; i>=0; i-- )
if( Pairs(i).Key==InKey && Pairs(i).Value==InValue )
{Pairs.Remove(i); Count++;}
if( Count )
Relax();
return Count;
unguardSlow;
}
TI* Find( const TK& Key )
{
guardSlow(TMap::Find);
for( INT i=Hash[(GetTypeHash(Key) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==Key )
return &Pairs(i).Value;
return NULL;
unguardSlow;
}
const TI* Find( const TK& Key ) const
{
guardSlow(TMap::Find);
for( INT i=Hash[(GetTypeHash(Key) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==Key )
return &Pairs(i).Value;
return NULL;
unguardSlow;
}
TI* FindPair( const TK& Key, const TK& Value )
{
guardSlow(TMap::Find);
for( INT i=Hash[(GetTypeHash(Key) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==Key && Pairs(i).Value==Value )
return &Pairs(i).Value;
return NULL;
unguardSlow;
}
void MultiFind( const TK& Key, TArray<TI>& Values )
{
guardSlow(TMap::MultiFind);
for( INT i=Hash[(GetTypeHash(Key) & (HashCount-1))]; i!=INDEX_NONE; i=Pairs(i).HashNext )
if( Pairs(i).Key==Key )
new(Values)TI(Pairs(i).Value);
unguardSlow;
}
friend FArchive& operator<<( FArchive& Ar, TMap& M )
{
guardSlow(TMap<<);
Ar << M.Pairs;
if( Ar.IsLoading() )
M.Rehash();
return Ar;
unguardSlow;
}
void Dump( FOutputDevice& Ar )
{
guard(TMap::Dump);
Ar.Logf( TEXT("TMap: %i items, %i hash slots"), Pairs.Num(), HashCount );
for( INT i=0; i<HashCount; i++ )
{
INT c=0;
for( INT j=Hash[i]; j!=INDEX_NONE; j=Pairs(j).HashNext )
c++;
Ar.Logf( TEXT(" Hash[%i] = %i"), i, c );
}
unguard;
}
class TIterator
{
public:
TIterator( TMap& InMap ) : Map( InMap ), Index( 0 ) {}
operator UBOOL() { return Index<Map.Pairs.Num(); }
void operator++() { ++Index; }
TPair* operator*() const { return &Map.Pairs(Index); }
TPair* operator->() const { return &Map.Pairs(Index); }
private:
TMap& Map;
INT Index;
};
class TFinder
{
public:
TFinder( TMap& InMap, TTypeInfo<TK>::ConstInitType InKey )
: Key( InKey )
, Map( InMap )
, Index( -1 )
{
++*this;
}
operator UBOOL()
{
return Index<Map.Pairs.Num();
}
void operator++()
{
do
{
++Index;
} while( Index<Map.Pairs.Num() && !(Map.Pairs(Index)==Key) );
}
TPair* operator*() const
{
return &Map.Pairs(Index);
}
TPair* operator->() const
{
return &Map.Pairs(Index);
}
private:
TK& Key;
TMap& Map;
INT Index;
};
friend class TIterator;
friend class TFinder;
};
/*----------------------------------------------------------------------------
TDoubleLinkedList.
----------------------------------------------------------------------------*/
//
// Simple double-linked list template.
//
template< class T > class TDoubleLinkedList : public T
{
public:
TDoubleLinkedList* Next;
TDoubleLinkedList** PrevLink;
void Unlink()
{
if( Next )
Next->PrevLink = PrevLink;
*PrevLink = Next;
}
void Link( TDoubleLinkedList*& Before )
{
if( Before )
Before->PrevLink = &Next;
Next = Before;
PrevLink = &Before;
Before = this;
}
};
/*----------------------------------------------------------------------------
FRainbowPtr.
----------------------------------------------------------------------------*/
//
// A union of pointers of all base types.
//
union CORE_API FRainbowPtr
{
// All pointers.
void* PtrVOID;
BYTE* PtrBYTE;
_WORD* PtrWORD;
DWORD* PtrDWORD;
QWORD* PtrQWORD;
FLOAT* PtrFLOAT;
// Conversion constructors.
FRainbowPtr() {}
FRainbowPtr( void* Ptr ) : PtrVOID(Ptr) {};
};
/*-----------------------------------------------------------------------------
The End.
-----------------------------------------------------------------------------*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -