[Native] TArray<BYTE> workaround for modern compilers
Posted: Fri Jan 02, 2015 2:35 pm
I have made a workaround today for TArray<BYTE> errors for myself in half a hour using explicit specialization and exporting of the specialized class.
At UnTemplate.h add right after end of TArray<T> definition:
Now my native AllObjects iterator perfectly compiles and works in Visual Studio 2012!
P.S: I am using some modified headers too (That are for compiling stuff on modern visual studios)...
At UnTemplate.h add right after end of TArray<T> definition:
Code: Select all
template<> class DLL_EXPORT TArray<BYTE> : public FArray {
public:
typedef BYTE ElementType;
TArray()
: FArray()
{}
TArray( INT InNum )
: FArray( InNum, 1 )
{}
TArray( const TArray& Other )
: FArray( Other.ArrayNum, 1 )
{
guardSlow(TArray::copyctor);
appMemcpy( &(*this)(0), &Other(0), ArrayNum );
unguardSlow;
}
TArray( ENoInit )
: FArray( E_NoInit )
{}
~TArray()
{
checkSlow(ArrayNum>=0);
checkSlow(ArrayMax>=ArrayNum);
Remove( 0, ArrayNum );
}
BYTE& operator()( INT i )
{
guardSlow(TArray::operator());
checkSlow(i>=0);
checkSlow(i<=ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((BYTE*)Data)[i];
unguardSlow;
}
const BYTE& operator()( INT i ) const
{
guardSlow(TArray::operator());
checkSlow(i>=0);
checkSlow(i<=ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((BYTE*)Data)[i];
unguardSlow;
}
BYTE Pop()
{
guardSlow(TArray::Pop);
check(ArrayNum>0);
checkSlow(ArrayMax>=ArrayNum);
BYTE Result = ((BYTE*)Data)[ArrayNum-1];
Remove( ArrayNum-1 );
return Result;
unguardSlow;
}
BYTE& Last( INT c=0 )
{
guardSlow(TArray::Last);
check(c<ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((BYTE*)Data)[ArrayNum-c-1];
unguardSlow;
}
const BYTE& Last( INT c=0 ) const
{
guardSlow(TArray::Last);
checkSlow(c<ArrayNum);
checkSlow(ArrayMax>=ArrayNum);
return ((BYTE*)Data)[ArrayNum-c-1];
unguardSlow;
}
void Shrink()
{
guardSlow(TArray::Shrink);
FArray::Shrink( 1 );
unguardSlow;
}
UBOOL FindItem( const BYTE& 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 BYTE& 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 );
// Serialize simple bytes which require no construction or destruction.
Ar << AR_INDEX(A.ArrayNum);
if( Ar.IsLoading() )
{
A.ArrayMax = A.ArrayNum;
A.Realloc( 1 );
}
Ar.Serialize( &A(0), A.Num() );
return Ar;
unguard;
}
void CountBytes( FArchive& Ar )
{
guardSlow(TArray::CountBytes);
FArray::CountBytes( Ar, 1 );
unguardSlow;
}
// Add, Insert, Remove, Empty interface.
INT Add( INT n=1 )
{
guardSlow(TArray::Add);
return FArray::Add( n, 1 );
unguardSlow;
}
void Insert( INT Index, INT Count=1 )
{
guardSlow(TArray::Insert);
FArray::Insert( Index, Count, 1 );
unguardSlow;
}
void InsertZeroed( INT Index, INT Count=1 )
{
guardSlow(TArray::InsertZeroed);
FArray::InsertZeroed( Index, Count, 1 );
unguardSlow;
}
void Remove( INT Index, INT Count=1 )
{
guardSlow(TArray::Remove);
check(Index>=0);
check(Index<=ArrayNum);
check(Index+Count<=ArrayNum);
FArray::Remove( Index, Count, 1 );
unguardSlow;
}
void Empty( INT Slack=0 )
{
guardSlow(TArray::Empty);
FArray::Empty( 1, Slack );
unguardSlow;
}
// Functions dependent on Add, Remove.
TArray& operator=( const TArray& Other )
{
guardSlow(TArray::operator=);
if( this != &Other )
{
Empty( Other.ArrayNum );
appMemcpy( &(*this)(0), &Other(0), ArrayNum );
//for( INT i=0; i<Other.ArrayNum; i++ )
// new( *this )BYTE( Other(i) );
}
return *this;
unguardSlow;
}
INT AddItem( const BYTE& Item )
{
guardSlow(TArray::AddItem);
INT Index=Add();
(*this)(Index)=Item;
return Index;
unguardSlow;
}
INT AddZeroed( INT n=1 )
{
guardSlow(TArray::AddZeroed);
return FArray::AddZeroed( 1, n );
unguardSlow;
}
INT AddUniqueItem( const BYTE& Item )
{
guardSlow(TArray::AddUniqueItem);
for( INT Index=0; Index<ArrayNum; Index++ )
if( (*this)(Index)==Item )
return Index;
return AddItem( Item );
unguardSlow;
}
INT RemoveItem( const BYTE& 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
{
public:
TIterator( TArray<BYTE>& InArray ) : Array(InArray), Index(-1) { ++*this; }
void operator++() { ++Index; }
void RemoveCurrent() { Array.Remove(Index--); }
INT GetIndex() const { return Index; }
operator UBOOL() const { return Index < Array.Num(); }
BYTE& operator*() const { return Array(Index); }
BYTE* operator->() const { return &Array(Index); }
BYTE& GetCurrent() const { return Array( Index ); }
BYTE& GetPrev() const { return Array( Index ? Index-1 : Array.Num()-1 ); }
BYTE& GetNext() const { return Array( Index<Array.Num()-1 ? Index+1 : 0 ); }
private:
TArray<BYTE>& Array;
INT Index;
};
};
P.S: I am using some modified headers too (That are for compiling stuff on modern visual studios)...