Base

Array

public class<T>
{
    @elements: T*
    @length:   int
    @size:     int
}
struct ix_base_Array
{
    ix_base_Object         parent;
    int                  (*append)(       ix_base_Array* self, ix_base_Object* element );
    ix_base_Object*         (*set)(       ix_base_Array* self, ix_base_Object* element, int index );
    ix_base_Object*      (*remove)(       ix_base_Array* self, int             index   );
    ix_base_Object_Ref*     (*get)( const ix_base_Array* self, int             index   );
    ix_base_Array*       (*delete)(       ix_base_Array** self );    
};
struct ix_base_Array_Ref
{
    ix_base_Object         parent;
    int                  (*append)(       ix_base_Array* self, ix_base_Object* element );
    ix_base_Object*         (*set)(       ix_base_Array* self, ix_base_Object* element, int index );
    ix_base_Object*      (*remove)(       ix_base_Array* self, int             index   );
    ix_base_Object_Ref*     (*get)( const ix_base_Array* self, int             index   );
};
#endif
struct ix_base_Array_private
{
    ix_base_Array    public;

    ix_base_Object** elements;
    int              length;
    int              size;

    ix_base_Object* (*ix_base_Object_delete)( ix_base_Object** self );    
};
#ifndef DELETE
#define DELETE( obj ) delete obj; obj = 0;
#endif

template <class T>
class Array : public Object {

public:
    T** elements;
    int length;
    int size;

    //static Array* New( int initialSize = 1 );
    //static Array* Delete( const Array* self );

//private:
public class Array<T> {

T[] elements = null;
int length   = 0;
int size     = 0;

Constructors

public new( initialSize: int = 1 )
{
    @elements = new T[initialSize]
    @length   = 0
    @size     = initialSize
}
ix_base_Array* ix_base_Array_new( ix_base_Array* self, int initialSize )
{
    if ( !self ) self = calloc( 1, ix_base_Array_sz() );

    if ( self )
    {
        ix_base_Object_new( (ix_base_Object*) self );
        {
            struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

            _self->elements              = calloc( initialSize, sizeof(ix_base_Object*) );
            _self->length                = 0;
            _self->size                  = initialSize;
            _self->ix_base_Object_delete = _self->public.parent.delete;

            _self->public.parent.delete  = (ix_base_Object*(*)(ix_base_Object**)) ix_base_Array_delete;
            _self->public.delete         = ix_base_Array_delete;
            _self->public.append         = append;
            _self->public.set            = set;
            _self->public.remove         = remove;
            _self->public.get            = get;
        }
    }

    return self;
}
Array( int initialSize )
{
    this->elements = new T*[initialSize];
    this->length   = 0;
    this->size     = 1;
}
public Array( int size )
{
    this.elements = new T[size];
    this.length   = 0;
    this.size     = size;
}

Destructors

ix_base_Array* ix_base_Array_delete( ix_base_Array** self )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) *self;

    if ( _self )
    {
        for ( int i=0; i < _self->size; i++ )
        {
            if ( _self->elements[i] ) _self->elements[i] = _self->elements[i]->delete( &_self->elements[i] );
        }
        free( _self->elements );
        _self->elements      = NULL;
        _self->length        = 0;
        _self->size          = 0;
        _self->public.append = NULL;
        _self->public.set    = NULL;
        _self->public.remove = NULL;
        _self->public.get    = NULL;

        *self = (ix_base_Array*) _self->ix_base_Object_delete( (ix_base_Object**) &self );
    }
    return NULL;
}
 ~Array()
{
    for ( int i=0; i < this->size; i++ )
    {
        if ( this->elements[i] ) DELETE( this->elements[i] );
    }

    delete this->elements;
    this->length = 0;
    this->size   = 0;
}
Array<T> delete()
{
    for ( int i=0; i < this.size; i++ )
    {
        this.elements[i] = null;
    }
    this.elements = null;
    this.length   = 0;
    this.size     = 0;

    return null;
}

Methods

Remove

public remove( index: int ): T
{
    if ( index < @size )
    {
        return @elements[index]!
    }
    else
    {
        return null
    }
}
ix_base_Object* remove( ix_base_Array* self, int index )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

    if ( index < _self->size )
    {
        ix_base_Object* element = _self->elements[index]; _self->elements[index] = NULL; return element;
    }
    else
    {
        return NULL;
    }
}
T* remove( int index )
{
    if ( index < this->size )
    {
        T* element = this->elements[index]; this->elements[index] = 0; return element;
    }
    else
    {
        return 0;
    }
}
public Object remove( int index )
{
    if ( index < this.size )
    {
        Object element = this.elements.GetValue( index ); this.elements.SetValue( default(T), index ); return element;
    }
    else
    {
        return null;
    }
}

Append

public append( element: T ): int
{
    if ( @length == @size )
    {
        double()
    }

    @elements[@length++] = element

    return @length - 1
}
int append( ix_base_Array* self, ix_base_Object* element )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

    if ( _self->length == _self->size )
    {
        doubleSize( self );
    }

    _self->elements[_self->length++] = element;

    return _self->length - 1;
}
int append( T* element )
{
    if ( this->length == this->size )
    {
        this->elements = (T**) doubleSize( this->size, (void**) this->elements );
        this->size     = this->size * 2;
    }

    this->elements[this->length++] = element;

    return this->length - 1;
}
public Object append( T element )
{
    if ( this.length == this.size )
    {
        doubleSize();
    }

    this.elements[this.length++] = element;

    return this.length - 1;
}

Set

ix_base_Object*
set( ix_base_Array* self, ix_base_Object* element, int index )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

    while ( index >= _self->size )
    {
        doubleSize( self );
    }

    ix_base_Object* existing = _self->elements[index]; _self->elements[index] = element;

    return existing;
}
T* set( T* element, int index )
{
    while ( index >= this->size )
    {
        this->elements = doubleSize( this->size, this->elements );
        this->size     = this->size * 2;
    }

    T* existing = this->elements[index]; this->elements[index] = element;

    return existing;
}

Const methods

Get

public const get( index: int ): T&
{
    if ( index < @size )
    {
        return @elements[index]
    }
    else
    {
        return null
    }
}
ix_base_Object_Ref* get( const ix_base_Array* self, int index )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

    if ( index < _self->size )
    {
        return (ix_base_Object_Ref*) _self->elements[index];
    }
    else
    {
        return NULL;
    }
}
T& get( int index )
{
    T* t = 0;

    if ( index < this->size )
    {
        return *this->elements[index];
    }
    else
    {
        return *t;
    }
}
public T get( int index )
{
    if ( index < this.size )
    {
        return this.elements[index];
    }
    else
    {
        return default(T);
    }
}
public const contains( slice: ix_base_Array& ): bool
{
}
public const indexOf( slice: ix_base_Array&, after: int = 0 ): int
{
}
public const substring( startIndex: int, length: int ): String
{
    return new( content: @content.slice( startIndex, length ) )
}
var ix_base_Array = new ix_base_Array<String>( 10 )
    ix_base_Array[0] = "Magic"
    ix_base_Array[1] = "Mushroom"
    ix_base_Array[]  = "Mike"

var str1: String  = ix_base_Array<0>
var str2: String& = ix_base_Array[1]!
void doubleSize( ix_base_Array* self )
{
    struct ix_base_Array_private* _self = (struct ix_base_Array_private*) self;

    int              new_size = _self->size * 2;
    ix_base_Object** tmp      = calloc( new_size, sizeof( ix_base_Object* ) );

    for ( int i=0; i < _self->size; i++ )
    {
        tmp[i] = _self->elements[i]; _self->elements[i] = NULL;
    }

    free( _self->elements );
    _self->elements = tmp;
    _self->size     = new_size;
}
void** doubleSize( int size, void** array )
{
    int    new_size = size * 2;
    void** tmp      = (void**) calloc( new_size, sizeof( void* ) );

    for ( int i=0; i < size; i++ )
    {
        tmp[i] = array[i]; array[i] = 0;
    }

    return tmp;
}
void doubleSize()
{
    int new_size = this.size * 2;
    T[] tmp = new T[new_size];

    for ( int i=0; i < this.size; i++ )
    {
        tmp[i] = this.elements[i]; this.elements[i] = default(T);
    }

    this.elements = null;
    this.elements = tmp;
    this.size     = new_size;
}
unsigned long ix_base_Array_sz()
{
    return sizeof( struct ix_base_Array_private ) + ix_base_Object_sz();
}

ix_base_Array_ref*
ix_base_Array_ref_cast( ix_base_Array* self )
{ return (ix_base_Array_ref*) self; }