Linux: Likely fix for gcc errors compiling SafeArray

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3602 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-08-05 01:39:31 +00:00
parent d231c537b9
commit d88cf47adb
13 changed files with 347 additions and 291 deletions

View File

@ -445,6 +445,10 @@
RelativePath="..\..\include\Utilities\SafeArray.h" RelativePath="..\..\include\Utilities\SafeArray.h"
> >
</File> </File>
<File
RelativePath="..\..\include\Utilities\SafeArray.inl"
>
</File>
<File <File
RelativePath="..\..\include\Utilities\ScopedPtr.h" RelativePath="..\..\include\Utilities\ScopedPtr.h"
> >

View File

@ -173,3 +173,14 @@ extern u64 GetTickFrequency();
extern u64 GetCPUTicks(); extern u64 GetCPUTicks();
extern wxString GetOSVersionString(); extern wxString GetOSVersionString();
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
extern void pcsx2_aligned_free(void* pmem);
// aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
# define _aligned_malloc pcsx2_aligned_malloc
# define _aligned_free pcsx2_aligned_free
# define _aligned_realloc pcsx2_aligned_realloc
#endif

View File

@ -15,18 +15,6 @@
#pragma once #pragma once
#include "MemcpyFast.h"
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
extern void pcsx2_aligned_free(void* pmem);
// aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
# define _aligned_malloc pcsx2_aligned_malloc
# define _aligned_free pcsx2_aligned_free
# define _aligned_realloc pcsx2_aligned_realloc
#endif
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets // Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
@ -60,9 +48,11 @@ extern void pcsx2_aligned_free(void* pmem);
#define safe_release( ptr ) \ #define safe_release( ptr ) \
((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL)) ((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
////////////////////////////////////////////////////////////////////////////////////////// // --------------------------------------------------------------------------------------
// Handy little class for allocating a resizable memory block, complete with // SafeArray
// exception-based error handling and automatic cleanup. // --------------------------------------------------------------------------------------
// Handy little class for allocating a resizable memory block, complete with exception
// error handling and automatic cleanup. A lightweight alternative to std::vector.
// //
template< typename T > template< typename T >
class SafeArray class SafeArray
@ -81,71 +71,29 @@ protected:
int m_size; // size of the allocation of memory int m_size; // size of the allocation of memory
protected: protected:
// Internal constructor for use by derived classes. This allows a derived class to SafeArray( const wxChar* name, T* allocated_mem, int initSize );
// use its own memory allocation (with an aligned memory, for example). virtual T* _virtual_realloc( int newsize );
// Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL. // A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
explicit SafeArray( const wxChar* name, T* allocated_mem, int initSize ) // builds only -- no bounds checking is done in release builds).
: Name( name ) T* _getPtr( uint i ) const
{ {
ChunkSize = DefaultChunkSize; IndexBoundsCheckDev( Name.c_str(), i, m_size );
m_ptr = allocated_mem; return &m_ptr[i];
m_size = initSize;
if( m_ptr == NULL )
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initSize));
}
virtual T* _virtual_realloc( int newsize )
{
T* retval = (T*)((m_ptr == NULL) ?
malloc( newsize * sizeof(T) ) :
realloc( m_ptr, newsize * sizeof(T) )
);
if( IsDebugBuild )
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
u32* fill = (u32*)&retval[m_size];
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
}
return retval;
} }
public: public:
virtual ~SafeArray() virtual ~SafeArray() throw();
{
safe_free( m_ptr );
}
explicit SafeArray( const wxChar* name=L"Unnamed" ) explicit SafeArray( const wxChar* name=L"Unnamed" );
: Name( name ) explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" );
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_size = 0;
}
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" ) void Dispose();
: Name( name ) void ExactAlloc( int newsize );
void MakeRoomFor( int newsize )
{ {
ChunkSize = DefaultChunkSize; if( newsize > m_size )
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) ); ExactAlloc( newsize );
m_size = initialSize;
if( (initialSize != 0) && (m_ptr == NULL) )
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initialSize));
}
// Clears the contents of the array to zero, and frees all memory allocations.
void Dispose()
{
m_size = 0;
safe_free( m_ptr );
} }
bool IsDisposed() const { return (m_ptr==NULL); } bool IsDisposed() const { return (m_ptr==NULL); }
@ -155,29 +103,6 @@ public:
// Returns the size of the memory allocation in bytes. // Returns the size of the memory allocation in bytes.
int GetSizeInBytes() const { return m_size * sizeof(T); } int GetSizeInBytes() const { return m_size * sizeof(T); }
// reallocates the array to the explicit size. Can be used to shrink or grow an
// array, and bypasses the internal threshold growth indicators.
void ExactAlloc( int newsize )
{
if( newsize == m_size ) return;
m_ptr = _virtual_realloc( newsize );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeArray::ExactAlloc) [oldsize=%d] [newsize=%d]", m_size, newsize)
);
m_size = newsize;
}
// Ensures that the allocation is large enough to fit data of the
// amount requested. The memory allocation is not resized smaller.
void MakeRoomFor( int newsize )
{
if( newsize > m_size )
ExactAlloc( newsize );
}
// Extends the containment area of the array. Extensions are performed // Extends the containment area of the array. Extensions are performed
// in chunks. // in chunks.
void GrowBy( int items ) void GrowBy( int items )
@ -195,25 +120,7 @@ public:
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); } T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); } const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
virtual SafeArray<T>* Clone() const virtual SafeArray<T>* Clone() const;
{
SafeArray<T>* retval = new SafeArray<T>( m_size );
memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
return retval;
}
protected:
// A safe array index fetcher. Throws an exception if the array index
// is outside the bounds of the array.
// Performance Considerations: This function adds quite a bit of overhead
// to array indexing and thus should be done infrequently if used in
// time-critical situations. Instead of using it from inside loops, cache
// the pointer into a local variable and use std (unsafe) C indexes.
T* _getPtr( uint i ) const
{
IndexBoundsCheckDev( Name.c_str(), i, m_size );
return &m_ptr[i];
}
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -244,45 +151,27 @@ protected:
uint m_length; // length of the array (active items, not buffer allocation) uint m_length; // length of the array (active items, not buffer allocation)
protected: protected:
virtual T* _virtual_realloc( int newsize ) virtual T* _virtual_realloc( int newsize );
void _MakeRoomFor_threshold( int newsize );
T* _getPtr( uint i ) const
{ {
return (T*)realloc( m_ptr, newsize * sizeof(T) ); IndexBoundsCheckDev( Name.c_str(), i, m_length );
return &m_ptr[i];
} }
public: public:
virtual ~SafeList() throw() virtual ~SafeList() throw();
{ explicit SafeList( const wxChar* name=L"Unnamed" );
safe_free( m_ptr ); explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" );
} virtual SafeList<T>* Clone() const;
explicit SafeList( const wxChar* name=L"Unnamed" ) void Remove( int index );
: Name( name ) void MakeRoomFor( int blockSize );
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_allocsize = 0;
m_length = 0;
}
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" ) T& New();
: Name( name ) int Add( const T& src );
{ T& AddNew( const T& src );
ChunkSize = DefaultChunkSize;
m_allocsize = initialSize;
m_length = 0;
m_ptr = (T*)malloc( initialSize * sizeof(T) );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeList::Constructor) [length=%d]", m_length)
);
for( int i=0; i<m_allocsize; ++i )
{
new (&m_ptr[i]) T();
}
}
// Returns the size of the list, as according to the array type. This includes // Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ. // mapped items only. The actual size of the allocation may differ.
@ -297,26 +186,6 @@ public:
m_length = m_allocsize; m_length = m_allocsize;
} }
// Ensures that the allocation is large enough to fit data of the
// amount requested. The memory allocation is not resized smaller.
void MakeRoomFor( int blockSize )
{
if( blockSize > m_allocsize )
{
const int newalloc = blockSize + ChunkSize;
m_ptr = _virtual_realloc( newalloc );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeList::MakeRoomFor) [oldlen=%d] [newlen=%d]", m_length, blockSize)
);
for( ; m_allocsize<newalloc; ++m_allocsize )
{
new (&m_ptr[m_allocsize]) T();
}
}
}
void GrowBy( int items ) void GrowBy( int items )
{ {
MakeRoomFor( m_length + ChunkSize + items + 1 ); MakeRoomFor( m_length + ChunkSize + items + 1 );
@ -328,13 +197,6 @@ public:
m_length = 0; m_length = 0;
} }
// Appends an item to the end of the list and returns a handle to it.
T& New()
{
_MakeRoomFor_threshold( m_length + 1 );
return m_ptr[m_length++];
}
// Gets an element of this memory allocation much as if it were an array. // Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); } T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
@ -345,63 +207,10 @@ public:
T& GetLast() { return m_ptr[m_length-1]; } T& GetLast() { return m_ptr[m_length-1]; }
const T& GetLast() const{ return m_ptr[m_length-1]; } const T& GetLast() const{ return m_ptr[m_length-1]; }
int Add( const T& src )
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_length++;
}
// Same as Add, but returns the handle of the new object instead of it's array index.
T& AddNew( const T& src )
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_ptr[m_length];
}
// Performs a standard array-copy removal of the given item. All items past the
// given item are copied over.
// DevBuilds : Generates assertion if the index is invalid.
void Remove( int index )
{
IndexBoundsCheckDev( Name.c_str(), index, m_length );
int copylen = m_length - index;
if( copylen > 0 )
memcpy_fast( &m_ptr[index], &m_ptr[index+1], copylen );
}
virtual SafeList<T>* Clone() const
{
SafeList<T>* retval = new SafeList<T>( m_length );
memcpy_fast( retval->m_ptr, m_ptr, sizeof(T) * m_length );
return retval;
}
protected:
void _MakeRoomFor_threshold( int newsize )
{
MakeRoomFor( newsize + ChunkSize );
}
// A safe array index fetcher. Throws an exception if the array index
// is outside the bounds of the array.
// Performance Considerations: This function adds quite a bit of overhead
// to array indexing and thus should be done infrequently if used in
// time-critical situations. Instead of using it from inside loops, cache
// the pointer into a local variable and use std (unsafe) C indexes.
T* _getPtr( uint i ) const
{
IndexBoundsCheckDev( Name.c_str(), i, m_length );
return &m_ptr[i];
}
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SafeAlignedArray class // SafeAlignedArray<T>
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Handy little class for allocating a resizable memory block, complete with // Handy little class for allocating a resizable memory block, complete with
// exception-based error handling and automatic cleanup. // exception-based error handling and automatic cleanup.
@ -413,49 +222,19 @@ class SafeAlignedArray : public SafeArray<T>
typedef SafeArray<T> _parent; typedef SafeArray<T> _parent;
protected: protected:
T* _virtual_realloc( int newsize ) T* _virtual_realloc( int newsize );
{
return (T*)( ( this->m_ptr == NULL ) ?
_aligned_malloc( newsize * sizeof(T), Alignment ) :
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
);
}
// Appends "(align: xx)" to the name of the allocation in devel builds.
// Maybe useful,maybe not... no harm in attaching it. :D
public: public:
using _parent::operator[]; using _parent::operator[];
virtual ~SafeAlignedArray() virtual ~SafeAlignedArray();
{
safe_aligned_free( this->m_ptr );
// mptr is set to null, so the parent class's destructor won't re-free it.
}
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) : explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
SafeArray<T>::SafeArray( name ) SafeArray<T>::SafeArray( name )
{ {
} }
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) : explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" );
SafeArray<T>::SafeArray( virtual SafeAlignedArray<T,Alignment>* Clone() const;
name,
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
initialSize
)
{
}
virtual SafeAlignedArray<T,Alignment>* Clone() const
{
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
memcpy_fast( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
return retval;
}
}; };
// For lack of a better place for now (they depend on SafeList so they can't go in StringUtil)
extern void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString& delims );
extern wxString JoinString( const SafeList<wxString>& src, const wxString& separator );

View File

@ -0,0 +1,277 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "MemcpyFast.h"
#include "SafeArray.h"
// Internal constructor for use by derived classes. This allows a derived class to
// use its own memory allocation (with an aligned memory, for example).
// Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
template< typename T >
SafeArray<T>::SafeArray( const wxChar* name, T* allocated_mem, int initSize )
: Name( name )
{
ChunkSize = DefaultChunkSize;
m_ptr = allocated_mem;
m_size = initSize;
if( m_ptr == NULL )
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initSize));
}
template< typename T >
T* SafeArray<T>::_virtual_realloc( int newsize )
{
T* retval = (T*)((m_ptr == NULL) ?
malloc( newsize * sizeof(T) ) :
realloc( m_ptr, newsize * sizeof(T) )
);
if( IsDebugBuild )
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
u32* fill = (u32*)&retval[m_size];
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
}
return retval;
}
template< typename T >
SafeArray<T>::~SafeArray() throw()
{
safe_free( m_ptr );
}
template< typename T >
SafeArray<T>::SafeArray( const wxChar* name=L"Unnamed" )
: Name( name )
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_size = 0;
}
template< typename T >
SafeArray<T>::SafeArray( int initialSize, const wxChar* name=L"Unnamed" )
: Name( name )
{
ChunkSize = DefaultChunkSize;
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) );
m_size = initialSize;
if( (initialSize != 0) && (m_ptr == NULL) )
throw Exception::OutOfMemory(name + wxsFormat(L" (SafeArray::constructor) [size=%d]", initialSize));
}
// Clears the contents of the array to zero, and frees all memory allocations.
template< typename T >
void SafeArray<T>::Dispose()
{
m_size = 0;
safe_free( m_ptr );
}
// reallocates the array to the explicit size. Can be used to shrink or grow an
// array, and bypasses the internal threshold growth indicators.
template< typename T >
void SafeArray<T>::ExactAlloc( int newsize )
{
if( newsize == m_size ) return;
m_ptr = _virtual_realloc( newsize );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeArray::ExactAlloc) [oldsize=%d] [newsize=%d]", m_size, newsize)
);
m_size = newsize;
}
template< typename T >
SafeArray<T>* SafeArray<T>::Clone() const
{
SafeArray<T>* retval = new SafeArray<T>( m_size );
memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
return retval;
}
// --------------------------------------------------------------------------------------
// SafeAlignedArray<T> (implementations)
// --------------------------------------------------------------------------------------
template< typename T, uint Alignment >
T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize )
{
return (T*)( ( this->m_ptr == NULL ) ?
_aligned_malloc( newsize * sizeof(T), Alignment ) :
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
);
}
// Appends "(align: xx)" to the name of the allocation in devel builds.
// Maybe useful,maybe not... no harm in attaching it. :D
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>::~SafeAlignedArray()
{
safe_aligned_free( this->m_ptr );
// mptr is set to null, so the parent class's destructor won't re-free it.
}
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>::SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) :
SafeArray<T>::SafeArray(
name,
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
initialSize
)
{
}
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>* SafeAlignedArray<T,Alignment>::Clone() const
{
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
memcpy_fast( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
return retval;
}
// --------------------------------------------------------------------------------------
// SafeList<T> (implementations)
// --------------------------------------------------------------------------------------
template< typename T >
T* SafeList<T>::_virtual_realloc( int newsize )
{
return (T*)realloc( m_ptr, newsize * sizeof(T) );
}
template< typename T >
SafeList<T>::~SafeList() throw()
{
safe_free( m_ptr );
}
template< typename T >
SafeList<T>::SafeList( const wxChar* name=L"Unnamed" )
: Name( name )
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_allocsize = 0;
m_length = 0;
}
template< typename T >
SafeList<T>::SafeList( int initialSize, const wxChar* name=L"Unnamed" )
: Name( name )
{
ChunkSize = DefaultChunkSize;
m_allocsize = initialSize;
m_length = 0;
m_ptr = (T*)malloc( initialSize * sizeof(T) );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeList::Constructor) [length=%d]", m_length)
);
for( int i=0; i<m_allocsize; ++i )
{
new (&m_ptr[i]) T();
}
}
// Ensures that the allocation is large enough to fit data of the
// amount requested. The memory allocation is not resized smaller.
template< typename T >
void SafeList<T>::MakeRoomFor( int blockSize )
{
if( blockSize > m_allocsize )
{
const int newalloc = blockSize + ChunkSize;
m_ptr = _virtual_realloc( newalloc );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name +
wxsFormat(L" (SafeList::MakeRoomFor) [oldlen=%d] [newlen=%d]", m_length, blockSize)
);
for( ; m_allocsize<newalloc; ++m_allocsize )
{
new (&m_ptr[m_allocsize]) T();
}
}
}
// Appends an item to the end of the list and returns a handle to it.
template< typename T >
T& SafeList<T>::New()
{
_MakeRoomFor_threshold( m_length + 1 );
return m_ptr[m_length++];
}
template< typename T >
int SafeList<T>::Add( const T& src )
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_length++;
}
// Same as Add, but returns the handle of the new object instead of it's array index.
template< typename T >
T& SafeList<T>::AddNew( const T& src )
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_ptr[m_length];
}
// Performs a standard array-copy removal of the given item. All items past the
// given item are copied over.
// DevBuilds : Generates assertion if the index is invalid.
template< typename T >
void SafeList<T>::Remove( int index )
{
IndexBoundsCheckDev( Name.c_str(), index, m_length );
int copylen = m_length - index;
if( copylen > 0 )
memcpy_fast( &m_ptr[index], &m_ptr[index+1], copylen );
}
template< typename T >
SafeList<T>* SafeList<T>::Clone() const
{
SafeList<T>* retval = new SafeList<T>( m_length );
memcpy_fast( retval->m_ptr, m_ptr, sizeof(T) * m_length );
return retval;
}
template< typename T >
void SafeList<T>::_MakeRoomFor_threshold( int newsize )
{
MakeRoomFor( newsize + ChunkSize );
}

View File

@ -109,10 +109,7 @@ public:
m_IsDisposed = true; m_IsDisposed = true;
} }
// This is needed the C++ standard likes making life suck for programmers. TlsVariable<T>& operator=( const T& src )
using BaseTlsVariable<T>::GetRef;
TlsVariable& operator=( const T& src )
{ {
GetRef() = src; GetRef() = src;
return *this; return *this;

View File

@ -15,6 +15,8 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Threading.h" #include "Threading.h"
#include "TlsVariable.inl"
#include "SafeArray.inl"
using namespace Threading; using namespace Threading;
@ -23,8 +25,6 @@ using namespace Threading;
// system deadlock. // system deadlock.
static const int MaxFormattedStringLength = 0x80000; static const int MaxFormattedStringLength = 0x80000;
#include "TlsVariable.inl"
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// FastFormatBuffers // FastFormatBuffers
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -41,13 +41,6 @@ __forceinline wxString fromAscii( const char* src )
// //
// Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make // Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make
// my own. // my own.
void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString& delims )
{
wxStringTokenizer parts( src, delims );
while( parts.HasMoreTokens() )
dest.Add( parts.GetNextToken() );
}
void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode ) void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode )
{ {
wxStringTokenizer parts( src, delims, mode ); wxStringTokenizer parts( src, delims, mode );
@ -61,20 +54,6 @@ void SplitString( wxArrayString& dest, const wxString& src, const wxString& deli
// //
// Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make // Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make
// my own. // my own.
wxString JoinString( const SafeList<wxString>& src, const wxString& separator )
{
wxString dest;
for( int i=0, len=src.GetLength(); i<len; ++i )
{
if( src[i].IsEmpty() ) continue;
if( !dest.IsEmpty() )
dest += separator;
dest += src[i];
}
return dest;
}
wxString JoinString( const wxArrayString& src, const wxString& separator ) wxString JoinString( const wxArrayString& src, const wxString& separator )
{ {
wxString dest; wxString dest;

View File

@ -17,6 +17,10 @@
#include "pxRadioPanel.h" #include "pxRadioPanel.h"
#include "pxStaticText.h" #include "pxStaticText.h"
#include "SafeArray.inl"
template class SafeArray<RadioPanelObjects>;
// =========================================================================================== // ===========================================================================================
// pxRadioPanel Implementations // pxRadioPanel Implementations
// =========================================================================================== // ===========================================================================================

View File

@ -26,6 +26,8 @@
#include "Elfheader.h" #include "Elfheader.h"
#include "Counters.h" #include "Counters.h"
#include "Utilities/SafeArray.inl"
using namespace R5900; using namespace R5900;

View File

@ -18,6 +18,7 @@
#include "App.h" #include "App.h"
#include "SaveState.h" #include "SaveState.h"
#include "ThreadedZipTools.h" #include "ThreadedZipTools.h"
#include "Utilities/SafeArray.inl"
BaseCompressThread::~BaseCompressThread() throw() BaseCompressThread::~BaseCompressThread() throw()

View File

@ -20,6 +20,7 @@
#include "MSWstuff.h" #include "MSWstuff.h"
#include "Utilities/Console.h" #include "Utilities/Console.h"
#include "Utilities/SafeArray.inl"
#include "DebugTools/Debug.h" #include "DebugTools/Debug.h"
#include <wx/textfile.h> #include <wx/textfile.h>

View File

@ -14,7 +14,7 @@
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Utilities/SafeArray.h" #include "Utilities/SafeArray.inl"
#include "MemoryCardFile.h" #include "MemoryCardFile.h"

View File

@ -26,6 +26,7 @@
#include "Dialogs/ModalPopups.h" #include "Dialogs/ModalPopups.h"
#include "Utilities/ThreadingDialogs.h" #include "Utilities/ThreadingDialogs.h"
#include "Utilities/SafeArray.inl"
// Allows us to force-disable threading for debugging/troubleshooting // Allows us to force-disable threading for debugging/troubleshooting
static const bool DisableThreading = static const bool DisableThreading =