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>
# include <System/Exception.h>
2010-12-04 16:14:34 +00:00
# include <System/Types.h>
# include "Interfaces.h"
2011-05-02 17:33:24 +00:00
# include <stdlib.h>
# include <string.h>
2010-12-04 16:14:34 +00:00
namespace System
{
namespace Collections
{
namespace Generic
{
/// <summary>
2011-01-16 00:47:37 +00:00
/// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and
/// manipulate lists.
2010-12-04 16:14:34 +00:00
/// </summary>
template < class T >
class List : public IList < T >
{
private :
static const int _defaultCapacity = 4 ;
2011-03-07 19:14:57 +00:00
static T * _emptyArray ;
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-05-02 17:33:24 +00:00
void EnsureCapacity ( int capacity ) ;
2010-12-04 16:14:34 +00:00
public :
2011-05-02 17:33:24 +00:00
int Count ( ) ; // Gets the number of elements actually contained in the List<>.
int getCapacity ( ) ; // Gets the total number of elements the internal data structure can hold without resizing.
void setCapacity ( int value ) ; // Sets the total number of elements the internal data structure can hold without resizing.
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
List ( ) ; // Initializes a new instance of the List<> class that is empty and has the default initial capacity.
List ( int capacity ) ; // Initializes a new instance of the List<> class that is empty and has the specified initial capacity.
List ( const List & obj ) ; // Copy constructor
~ List ( ) ; // Destructor
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
void Add ( T & item ) ; // Adds an element to the end of the list
void Clear ( ) ; //Removes all elements from the list
bool Contains ( T & item ) // Determines whether an element is in the List<>.
2011-03-07 19:14:57 +00:00
{
for ( int i = 0 ; i < _size ; i + + )
{
if ( _items [ i ] = = item )
{
return true ;
}
}
return false ;
}
void CopyTo ( T array [ ] ) // Copies the entire List<> to a compatible one-dimensional array, starting at the beginning of the target array.
{
Array : : Copy ( _items , 0 , array , 0 , _size ) ;
}
void CopyTo ( T array [ ] , int arrayIndex ) // Copies the entire List<> to a compatible one-dimensional array, starting at the specified index of the target array.
{
Array : : Copy ( _items , 0 , array , arrayIndex , _size ) ;
}
2011-05-02 17:33:24 +00:00
int IndexOf ( T & item ) // Searches for the specified object and returns the zero-based index of the first occurrence within the entire List<>.
2011-03-07 19:14:57 +00:00
{
return Array : : IndexOf ( _items , item , 0 , _size ) ;
}
2011-05-02 17:33:24 +00:00
void Insert ( int index , T & item ) // Inserts an element into the List<> at the specified index.
2011-03-07 19:14:57 +00:00
{
if ( index > _size )
{
throw ArgumentOutOfRangeException ( " index " , " Index must be within the bounds of the List. " ) ;
}
if ( _size = = Array : : Length ( _items ) )
{
EnsureCapacity ( _size + 1 ) ;
}
if ( index < _size )
{
Array : : Copy ( _items , index , _items , index + 1 , _size - index ) ;
}
_items [ index ] = item ;
_size + + ;
_version + + ;
}
2011-05-02 17:33:24 +00:00
bool Remove ( T & item ) // Removes the first occurrence of a specific object from the List<>.
2011-03-07 19:14:57 +00:00
{
int index = IndexOf ( item ) ;
if ( index > = 0 )
{
RemoveAt ( index ) ;
return true ;
}
return false ;
}
2011-05-02 17:33:24 +00:00
void RemoveAt ( int index ) ; // Removes the element at the specified index of the List<>.
2011-03-07 19:14:57 +00:00
void RemoveRange ( int index , int count ) // Removes a range of elements from the List<>.
{
if ( ( index < 0 ) | | ( count < 0 ) )
{
throw ArgumentOutOfRangeException ( ( index < 0 ) ? " index " : " count " , " Non-negative number required. " ) ;
}
if ( ( _size - index ) < count )
{
throw ArgumentException ( " 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. " ) ;
}
if ( count > 0 )
{
_size - = count ;
if ( index < _size )
{
Array : : Copy ( _items , index + count , _items , index , _size - index ) ;
}
Array : : Clear ( _items , _size , count ) ;
_version + + ;
}
}
void Reverse ( )
{
Reverse ( 0 , Count ( ) ) ;
}
void Reverse ( int index , int count )
{
if ( ( index < 0 ) | | ( count < 0 ) )
{
throw ArgumentOutOfRangeException ( ( index < 0 ) ? " index " : " count " , " Non-negative number required. " ) ;
}
if ( ( _size - index ) < count )
{
throw ArgumentException ( " 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. " ) ;
}
Array : : Reverse ( _items , index , count ) ;
_version + + ;
}
2011-05-02 17:33:24 +00:00
T * ToArray ( )
2011-03-07 19:14:57 +00:00
{
return _items ;
}
void TrimExcess ( )
{
int num = ( int ) ( Array : : Length ( _items ) * 0.9 ) ;
if ( _size < num )
{
2011-05-02 17:33:24 +00:00
setCapacity ( _size ) ;
2011-03-07 19:14:57 +00:00
}
}
2011-05-02 17:33:24 +00:00
T & operator [ ] ( int index ) ;
List < T > & operator = ( const List & other ) ;
2011-03-07 19:14:57 +00:00
} ;
2011-05-02 17:33:24 +00:00
//////////////////////////////////////////////////////////////////////
2011-03-07 19:14:57 +00:00
template < class T >
2011-05-02 17:33:24 +00:00
List < T > : : List ( )
2011-03-07 19:14:57 +00:00
{
{
2011-05-02 17:33:24 +00:00
_actualSize = _defaultCapacity ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
_size = 0 ;
_items = ( T * ) malloc ( _actualSize * sizeof ( T ) ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
if ( _items = = null )
throw OutOfMemoryException ( ) ;
2011-03-07 19:14:57 +00:00
}
2011-05-02 17:33:24 +00:00
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
List < T > : : List ( int capacity )
{
if ( capacity < 0 )
throw ArgumentOutOfRangeException ( " capacity " , " Non-negative number required. " ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
_actualSize = capacity ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
_size = 0 ;
_items = ( T ) malloc ( _actualSize * sizeof ( T ) ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
if ( _items = = null )
throw OutOfMemoryException ( ) ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
List < T > : : List ( const List < T > & obj )
{
_items = ( T * ) malloc ( sizeof ( T ) * obj . _actualSize ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
if ( _items = = null )
throw OutOfMemoryException ( ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
memcpy ( _items , obj . _items , sizeof ( T ) * obj . _actualSize ) ;
_actualSize = obj . _actualSize ;
_size = obj . _size ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
List < T > : : ~ List ( )
{
if ( _items )
2011-03-07 19:14:57 +00:00
{
2011-05-02 17:33:24 +00:00
free ( _items ) ;
_items = null ;
2011-03-07 19:14:57 +00:00
}
2011-05-02 17:33:24 +00:00
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
int List < T > : : getCapacity ( )
{
return _actualSize ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
void List < T > : : setCapacity ( int value )
{
_size = value ;
if ( _size ! = 0 )
{
// change array memory size
// if new size is larger than current
// or new size is less then half of the current
if ( ( _size > _actualSize ) | | ( _size < _actualSize / 2 ) )
{
_actualSize = _size ;
_items = ( T * ) realloc ( _items , sizeof ( T ) * _size ) ;
if ( _items = = null )
throw OutOfMemoryException ( ) ;
}
}
else
Clear ( ) ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
int List < T > : : Count ( )
{
return _size ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
void List < T > : : Add ( T & item )
{
_size + + ;
if ( _size > _actualSize )
{
_actualSize * = 2 ;
_items = ( T * ) realloc ( _items , sizeof ( T ) * _actualSize ) ;
if ( _items = = null )
throw OutOfMemoryException ( ) ;
}
_items [ _size - 1 ] = item ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
void List < T > : : Clear ( )
{
_size = 0 ;
_items = ( T * ) realloc ( _items , sizeof ( T ) * _defaultCapacity ) ;
// set initial memory size again
_actualSize = _defaultCapacity ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
void List < T > : : EnsureCapacity ( int min )
{
if ( _size < min )
2011-03-07 19:14:57 +00:00
{
2011-05-02 17:33:24 +00:00
int num = ( _size = = 0 ) ? 4 : ( _size * 2 ) ;
if ( num < min )
2011-03-07 19:14:57 +00:00
{
2011-05-02 17:33:24 +00:00
num = min ;
2011-03-07 19:14:57 +00:00
}
2011-05-02 17:33:24 +00:00
setCapacity ( num ) ;
2011-03-07 19:14:57 +00:00
}
2011-05-02 17:33:24 +00:00
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
void List < T > : : RemoveAt ( int index )
{
if ( index < 0 | | index > = _size )
throw ArgumentOutOfRangeException ( " index " , " Index was out of range. Must be non-negative and less than the size of the collection. " ) ;
if ( _size = = 1 )
Clear ( ) ;
else
{
// otherwise, shift array elements
for ( int i = index ; i < _size - 1 ; i + + )
_items [ i ] = _items [ i + 1 ] ;
// decrease array size
_size - - ;
2011-03-07 19:14:57 +00:00
}
2011-05-02 17:33:24 +00:00
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
T & List < T > : : operator [ ] ( int index )
{
if ( index > = _size )
throw ArgumentOutOfRangeException ( " index " ) ;
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
return _items [ index ] ;
}
2011-03-07 19:14:57 +00:00
2011-05-02 17:33:24 +00:00
template < class T >
List < T > & List < T > : : operator = ( const List < T > & other )
{
if ( this = = & other ) // in case somebody tries assign array to itself
return * this ;
if ( other . _size = = 0 ) // is other array is empty -- clear this array
Clear ( ) ;
Capacity ( other . _size ) ; // set size
memcpy ( _items , other . _items , sizeof ( T ) * other . _size ) ;
return * this ;
}
2010-12-04 16:14:34 +00:00
}
}
}
# endif //_SYSTEM_COLLECTIONS_GENERIC_LIST_