/[pcsx2_0.9.7]/trunk/common/include/Utilities/SafeArray.h
ViewVC logotype

Diff of /trunk/common/include/Utilities/SafeArray.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/common/include/Utilities/SafeArray.h	2010/09/07 06:28:05	61
+++ trunk/common/include/Utilities/SafeArray.h	2010/09/07 11:08:22	62
@@ -15,18 +15,6 @@
 
 #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
@@ -60,9 +48,11 @@
 #define safe_release( ptr ) \
 	((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
 
-//////////////////////////////////////////////////////////////////////////////////////////
-// Handy little class for allocating a resizable memory block, complete with
-// exception-based error handling and automatic cleanup.
+// --------------------------------------------------------------------------------------
+//  SafeArray
+// --------------------------------------------------------------------------------------
+// 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 >
 class SafeArray
@@ -77,63 +67,33 @@
 	int			ChunkSize;
 
 protected:
-	T*		m_ptr;
-	int		m_size;				// size of the allocation of memory
+	T*			m_ptr;
+	int			m_size;			// size of the allocation of memory
 
 protected:
-	// 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.
-	explicit 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();
-	}
+	SafeArray( const wxChar* name, T* allocated_mem, int initSize );
+	virtual T* _virtual_realloc( int newsize );
 
-	virtual T* _virtual_realloc( int newsize )
+	// A safe array index fetcher.  Asserts if the index is out of bounds (dev and debug
+	// builds only -- no bounds checking is done in release builds).
+	T* _getPtr( uint i ) const
 	{
-		return (T*)((m_ptr == NULL) ?
-			malloc( newsize * sizeof(T) ) :
-			realloc( m_ptr, newsize * sizeof(T) )
-		);
+		IndexBoundsAssumeDev( Name.c_str(), i, m_size );
+		return &m_ptr[i];
 	}
 
 public:
-	virtual ~SafeArray()
-	{
-		safe_free( m_ptr );
-	}
-
-	explicit SafeArray( const wxChar* name=L"Unnamed" )
-		: Name( name )
-	{
-		ChunkSize	= DefaultChunkSize;
-		m_ptr		= NULL;
-		m_size		= 0;
-	}
-
-	explicit 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;
+	virtual ~SafeArray() throw();
 
-		if( (initialSize != 0) && (m_ptr == NULL) )
-			throw Exception::OutOfMemory();
-	}
-
-	// Clears the contents of the array to zero, and frees all memory allocations.
-	void Dispose()
+	explicit SafeArray( const wxChar* name=L"Unnamed" );
+	explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" );
+	
+	void Dispose();
+	void ExactAlloc( int newsize );
+	void MakeRoomFor( int newsize )
 	{
-		m_size = 0;
-		safe_free( m_ptr );
+		if( newsize > m_size )
+			ExactAlloc( newsize );
 	}
 
 	bool IsDisposed() const { return (m_ptr==NULL); }
@@ -143,36 +103,6 @@
 	// Returns the size of the memory allocation in bytes.
 	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(
-				wxsFormat(	// english (for diagnostic)
-					L"Out-of-memory on SafeArray block re-allocation.\n"
-					L"Old size: %d bytes, New size: %d bytes.",
-					m_size, newsize
-				),
-				// internationalized!
-				wxsFormat( _("Out of memory, trying to allocate %d bytes."), 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
 	// in chunks.
 	void GrowBy( int items )
@@ -190,25 +120,7 @@
 	T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
 	const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
 
-	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];
-	}
+	virtual SafeArray<T>* Clone() const;
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -239,42 +151,27 @@
 	uint	m_length;			// length of the array (active items, not buffer allocation)
 
 protected:
-	virtual T* _virtual_realloc( int newsize )
-	{
-		return (T*)realloc( m_ptr, newsize * sizeof(T) );
-	}
-
-public:
-	virtual ~SafeList() throw()
-	{
-		safe_free( m_ptr );
-	}
+	virtual T* _virtual_realloc( int newsize );
+	void _MakeRoomFor_threshold( int newsize );
 
-	explicit SafeList( const wxChar* name=L"Unnamed" ) :
-		Name( name )
-	,	ChunkSize( DefaultChunkSize )
-	,	m_ptr( NULL )
-	,	m_allocsize( 0 )
-	,	m_length( 0 )
+	T* _getPtr( uint i ) const
 	{
+		IndexBoundsAssumeDev( Name.c_str(), i, m_length );
+		return &m_ptr[i];
 	}
 
-	explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" ) :
-		Name( name )
-	,	ChunkSize( DefaultChunkSize )
-	,	m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
-	,	m_allocsize( initialSize )
-	,	m_length( 0 )
-	{
-		if( m_ptr == NULL )
-			throw Exception::OutOfMemory();
-
-		for( int i=0; i<m_allocsize; ++i )
-		{
-			new (&m_ptr[i]) T();
-		}
-
-	}
+public:
+	virtual ~SafeList() throw();
+	explicit SafeList( const wxChar* name=L"Unnamed" );
+	explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" );
+	virtual SafeList<T>* Clone() const;
+
+	void Remove( int index );
+	void MakeRoomFor( int blockSize );
+
+	T& New();
+	int Add( const T& src );
+	T& AddNew( const T& src );
 
 	// 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.
@@ -289,35 +186,6 @@
 		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(
-					// English Diagnostic message:
-					wxsFormat(
-						L"Out-of-memory on SafeList block re-allocation.\n"
-						L"Name: %s, Old size: %d bytes, New size: %d bytes",
-						Name.c_str(), m_allocsize, newalloc
-					),
-
-					wxsFormat( _("Out of memory, trying to allocate %d bytes."), newalloc )
-				);
-			}
-
-			for( ; m_allocsize<newalloc; ++m_allocsize )
-			{
-				new (&m_ptr[m_allocsize]) T();
-			}
-		}
-	}
-
 	void GrowBy( int items )
 	{
 		MakeRoomFor( m_length + ChunkSize + items + 1 );
@@ -329,13 +197,6 @@
 		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.
 	// DevBuilds : Generates assertion if the index is invalid.
 	T& operator[]( int idx )				{ return *_getPtr( (uint)idx ); }
@@ -346,63 +207,10 @@
 
 	T& GetLast()			{ 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
 // exception-based error handling and automatic cleanup.
@@ -411,48 +219,22 @@
 template< typename T, uint Alignment >
 class SafeAlignedArray : public SafeArray<T>
 {
-protected:
-	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 )
-		);
-	}
+	typedef SafeArray<T> _parent;
 
-	// Appends "(align: xx)" to the name of the allocation in devel builds.
-	// Maybe useful,maybe not... no harm in attaching it. :D
+protected:
+	T* _virtual_realloc( int newsize );
 
 public:
-	virtual ~SafeAlignedArray()
-	{
-		safe_aligned_free( this->m_ptr );
-		// mptr is set to null, so the parent class's destructor won't re-free it.
-	}
+	using _parent::operator[];
+
+	virtual ~SafeAlignedArray() throw();
 
 	explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
 		SafeArray<T>::SafeArray( name )
 	{
 	}
 
-	explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) :
-		SafeArray<T>::SafeArray(
-			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;
-	}
+	explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" );
+	virtual SafeAlignedArray<T,Alignment>* Clone() const;
 };
 
-
-// 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 void JoinString( wxString& dest, const SafeList<wxString>& src, const wxString& separator );

 

  ViewVC Help
Powered by ViewVC 1.1.22