2010-12-04 16:14:34 +00:00
/********************************************************
* List . h *
* *
* XFX Generic List definition file *
* Copyright <EFBFBD> XFX Team . All Rights Reserved *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef _SYSTEM_COLLECTIONS_GENERIC_LIST_
# define _SYSTEM_COLLECTIONS_GENERIC_LIST_
2011-03-07 19:14:57 +00:00
# include <System/Array.h>
2012-03-29 22:02:43 +00:00
# include <System/FrameworkResources.h>
2011-11-07 01:29:50 +00:00
# include <System/Object.h>
2012-03-29 22:02:43 +00:00
# include <System/String.h>
2010-12-04 16:14:34 +00:00
# include "Interfaces.h"
2011-05-02 17:33:24 +00:00
# include <stdlib.h>
# include <string.h>
2012-03-29 22:02:43 +00:00
# include <sassert.h>
2011-11-07 01:29:50 +00:00
2010-12-04 16:14:34 +00:00
namespace System
{
namespace Collections
{
namespace Generic
{
2011-11-07 01:29:50 +00:00
// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.
2012-09-28 20:36:02 +00:00
// NOTE: types used with the List<T> class must provide at least an == operator.
template < typename T >
class List : public IList < T > , public Object
2010-12-04 16:14:34 +00:00
{
private :
2012-09-28 20:36:02 +00:00
static const int defaultCapacity = 4 ;
2011-03-07 19:14:57 +00:00
T * _items ;
2010-12-04 16:14:34 +00:00
int _size ;
2011-05-02 17:33:24 +00:00
int _actualSize ;
2010-12-04 16:14:34 +00:00
int _version ;
2011-11-07 01:29:50 +00:00
void EnsureCapacity ( int capacity )
{
if ( _actualSize < capacity )
{
2012-09-28 20:36:02 +00:00
int num = ( _actualSize = = 0 ) ? defaultCapacity : _actualSize * 2 ;
2011-11-07 01:29:50 +00:00
if ( num > 0x7fefffff )
{
num = 0x7fefffff ;
}
if ( num < capacity )
{
num = capacity ;
}
2012-03-29 22:02:43 +00:00
setCapacity ( num ) ;
2011-11-07 01:29:50 +00:00
}
}
2010-12-04 16:14:34 +00:00
public :
2011-11-07 01:29:50 +00:00
// Gets the number of elements actually contained in the List<>.
2012-03-29 22:02:43 +00:00
int Count ( ) const
2011-11-07 01:29:50 +00:00
{
return _size ;
}
// Gets the total number of elements the internal data structure can hold without resizing.
2012-03-29 22:02:43 +00:00
int getCapacity ( ) const
2011-11-07 01:29:50 +00:00
{
return _actualSize ;
}
// Sets the total number of elements the internal data structure can hold without resizing.
2012-03-29 22:02:43 +00:00
void setCapacity ( const int value )
2011-11-07 01:29:50 +00:00
{
if ( value < _size )
return ;
if ( value ! = _actualSize )
{
if ( value > 0 )
{
T * destinationArray = new T [ value ] ;
if ( _size > 0 )
{
2012-09-28 20:36:02 +00:00
for ( int i = 0 ; i < _size ; i + + )
{
destinationArray [ i ] = _items [ i ] ;
}
2011-11-07 01:29:50 +00:00
}
delete [ ] _items ;
_items = destinationArray ;
}
else
{
delete [ ] _items ;
_items = new T [ 0 ] ;
}
_actualSize = value ;
}
}
2012-03-29 22:02:43 +00:00
bool IsReadOnly ( ) const
2011-11-07 01:29:50 +00:00
{
return false ;
}
// Initializes a new instance of the List<> class that is empty and has the default initial capacity.
List ( )
2012-09-28 20:36:02 +00:00
: _size ( 0 ) , _actualSize ( defaultCapacity ) , _version ( 0 )
2011-11-07 01:29:50 +00:00
{
_items = new T [ _actualSize ] ;
}
// Initializes a new instance of the List<> class that is empty and has the specified initial capacity.
2012-03-29 22:02:43 +00:00
List ( const int capacity )
2012-09-28 20:36:02 +00:00
: _size ( 0 ) , _actualSize ( ( capacity < 0 ) ? defaultCapacity : capacity ) , _version ( 0 )
2011-11-07 01:29:50 +00:00
{
_items = new T [ _actualSize ] ;
}
2011-03-07 19:14:57 +00:00
2012-03-29 22:02:43 +00:00
// Copy constructor
List ( const List < T > & obj )
2012-09-28 20:36:02 +00:00
: _size ( obj . _size ) , _actualSize ( obj . _actualSize ) , _version ( obj . _version )
2012-03-29 22:02:43 +00:00
{
_items = new T [ obj . _actualSize ] ;
2012-09-28 20:36:02 +00:00
for ( int i = 0 ; i < obj . _size ; i + + )
{
_items [ i ] = obj . _items [ i ] ;
}
2012-03-29 22:02:43 +00:00
}
2011-03-07 19:14:57 +00:00
2011-11-07 01:29:50 +00:00
~ List ( )
{
delete [ ] _items ;
}
// Adds an element to the end of the list
2012-03-29 22:02:43 +00:00
void Add ( const T & item )
2011-11-07 01:29:50 +00:00
{
2012-03-29 22:02:43 +00:00
if ( _size = = _actualSize )
2011-11-07 01:29:50 +00:00
{
EnsureCapacity ( _size + 1 ) ;
}
2012-09-28 20:36:02 +00:00
_items [ _size + + ] = T ( item ) ;
2011-11-07 01:29:50 +00:00
_version + + ;
}
//Removes all elements from the list
void Clear ( )
{
if ( _size > 0 )
{
2012-03-29 22:02:43 +00:00
delete [ ] _items ;
2011-11-07 01:29:50 +00:00
_items = new T [ _actualSize ] ;
_size = 0 ;
}
_version + + ;
}
// Determines whether an element is in the List<>.
2012-03-29 22:02:43 +00:00
bool Contains ( const T & item ) const
2011-03-07 19:14:57 +00:00
{
for ( int i = 0 ; i < _size ; i + + )
{
2012-03-29 22:02:43 +00:00
if ( _items [ i ] = = item )
2011-03-07 19:14:57 +00:00
{
return true ;
2012-03-29 22:02:43 +00:00
}
2011-03-07 19:14:57 +00:00
}
return false ;
}
2011-11-07 01:29:50 +00:00
// Copies the entire List<> to a compatible one-dimensional array, starting at the specified index of the target array.
2012-03-29 22:02:43 +00:00
void CopyTo ( T array [ ] , const int arrayIndex ) const
2011-03-07 19:14:57 +00:00
{
2012-09-28 20:36:02 +00:00
sassert ( array ! = null , String : : Format ( " array; %s " , FrameworkResources : : ArgumentNull_Generic ) ) ;
for ( int i = 0 , j = arrayIndex ; i < _size ; i + + , j + + )
{
array [ j ] = _items [ i ] ;
}
}
int GetType ( ) const
{
//! TODO: implement
2011-03-07 19:14:57 +00:00
}
2011-11-07 01:29:50 +00:00
// Searches for the specified object and returns the zero-based index of the first occurrence within the entire List<>.
2012-03-29 22:02:43 +00:00
int IndexOf ( const T & item ) const
2011-03-07 19:14:57 +00:00
{
2012-09-28 20:36:02 +00:00
for ( int i = 0 ; i < _size ; i + + )
{
if ( _items [ i ] = = item )
return i ;
}
return - 1 ;
2011-03-07 19:14:57 +00:00
}
2011-11-07 01:29:50 +00:00
// Inserts an element into the List<> at the specified index.
2012-03-29 22:02:43 +00:00
void Insert ( const int index , const T & item )
2011-03-07 19:14:57 +00:00
{
2012-03-29 22:02:43 +00:00
sassert ( index < _size , " Index must be within the bounds of the List. " ) ;
if ( _size = = _actualSize )
2011-03-07 19:14:57 +00:00
{
EnsureCapacity ( _size + 1 ) ;
}
if ( index < _size )
{
2012-09-28 20:36:02 +00:00
for ( int i = index , j = index + 1 ; i < _size - index ; i + + , j + + )
{
_items [ j ] = _items [ i ] ;
}
2011-03-07 19:14:57 +00:00
}
2012-09-28 20:36:02 +00:00
_items [ index ] = T ( item ) ;
2011-03-07 19:14:57 +00:00
_size + + ;
_version + + ;
}
2011-11-07 01:29:50 +00:00
// Removes the first occurrence of a specific object from the List<>.
2012-03-29 22:02:43 +00:00
bool Remove ( const T & item )
2011-03-07 19:14:57 +00:00
{
int index = IndexOf ( item ) ;
if ( index > = 0 )
{
RemoveAt ( index ) ;
return true ;
}
return false ;
}
2011-11-07 01:29:50 +00:00
// Removes the element at the specified index of the List<>.
2012-03-29 22:02:43 +00:00
void RemoveAt ( const int index )
2011-11-07 01:29:50 +00:00
{
2012-09-28 20:36:02 +00:00
for ( int i = index + 1 , j = index ; i < _size - index ; i + + , j + + )
{
_items [ j ] = _items [ i ] ;
}
2011-11-07 01:29:50 +00:00
_size - - ;
_version + + ;
}
// Removes a range of elements from the List<>.
2012-03-29 22:02:43 +00:00
void RemoveRange ( const int index , const int count )
2011-03-07 19:14:57 +00:00
{
2012-03-29 22:02:43 +00:00
sassert ( index > = 0 , String : : Format ( " index; %s " , FrameworkResources : : ArgumentOutOfRange_NeedNonNegNum ) ) ;
sassert ( count > = 0 , String : : Format ( " count; %s " , FrameworkResources : : ArgumentOutOfRange_NeedNonNegNum ) ) ;
sassert ( ! ( ( _size - index ) < count ) , " Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. " ) ;
2011-03-07 19:14:57 +00:00
if ( count > 0 )
{
_size - = count ;
if ( index < _size )
{
2012-09-28 20:36:02 +00:00
for ( int i = index + count , j = index ; i < _size - index ; i + + , j + + )
{
_items [ j ] = _items [ i ] ;
}
}
for ( int i = _size ; i < count ; i + + )
{
_items [ i ] = T ( ) ;
2011-03-07 19:14:57 +00:00
}
_version + + ;
}
}
void Reverse ( )
{
2011-11-07 01:29:50 +00:00
Reverse ( 0 , _size ) ;
2011-03-07 19:14:57 +00:00
}
2012-03-29 22:02:43 +00:00
void Reverse ( const int index , const int count )
2011-03-07 19:14:57 +00:00
{
2012-03-29 22:02:43 +00:00
sassert ( index > = 0 , String : : Format ( " index; %s " , FrameworkResources : : ArgumentOutOfRange_NeedNonNegNum ) ) ;
sassert ( count > = 0 , String : : Format ( " count; %s " , FrameworkResources : : ArgumentOutOfRange_NeedNonNegNum ) ) ;
sassert ( ! ( ( _size - index ) < count ) , " Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. " ) ;
2012-09-28 20:36:02 +00:00
int num = index ;
int num2 = ( index + count ) - 1 ;
while ( num < num2 )
{
T obj2 = _items [ num ] ;
_items [ num ] = _items [ num2 ] ;
_items [ num2 ] = obj2 ;
num + + ;
num2 - - ;
}
2011-03-07 19:14:57 +00:00
_version + + ;
}
2012-03-29 22:02:43 +00:00
T * ToArray ( ) const
2011-03-07 19:14:57 +00:00
{
2011-11-07 01:29:50 +00:00
T * destinationArray = new T [ _size ] ;
2012-09-28 20:36:02 +00:00
for ( int i = 0 ; i < _size ; i + + )
destinationArray [ i ] = _items [ i ] ;
2011-11-07 01:29:50 +00:00
return destinationArray ;
}
2012-03-29 22:02:43 +00:00
const char * ToString ( ) const
2011-11-07 01:29:50 +00:00
{
2012-09-28 20:36:02 +00:00
return " List<T> " ;
2011-03-07 19:14:57 +00:00
}
void TrimExcess ( )
{
2012-03-29 22:02:43 +00:00
int num = ( int ) ( _actualSize * 0.9 ) ;
2011-03-07 19:14:57 +00:00
if ( _size < num )
{
2011-05-02 17:33:24 +00:00
setCapacity ( _size ) ;
2011-03-07 19:14:57 +00:00
}
}
2012-09-28 20:36:02 +00:00
T & operator [ ] ( const int index )
2011-11-07 01:29:50 +00:00
{
return _items [ index ] ;
}
2012-03-29 22:02:43 +00:00
const List < T > & operator = ( const List < T > other )
2011-11-07 01:29:50 +00:00
{
delete [ ] _items ;
_actualSize = other . _actualSize ;
_size = other . _size ;
_items = new T [ other . _actualSize ] ;
2012-09-28 20:36:02 +00:00
for ( int i = 0 ; i < other . _size ; i + + )
2011-11-07 01:29:50 +00:00
{
2012-09-28 20:36:02 +00:00
_items [ i ] = other . _items [ i ] ;
2011-11-07 01:29:50 +00:00
}
2011-03-07 19:14:57 +00:00
2012-09-28 20:36:02 +00:00
_version = other . _version ;
return * this ;
2011-11-07 01:29:50 +00:00
}
2012-09-28 20:36:02 +00:00
} ;
2010-12-04 16:14:34 +00:00
}
}
}
# endif //_SYSTEM_COLLECTIONS_GENERIC_LIST_