pushrbx icon

Untitled

pushrbx | PRO | 01/17/14 12:31:59 PM UTC | 0 ⭐ | 387 👁️ | Never ⏰ | []
C++ |

7.54 KB

|

None

|

0 👍

/

0 👎

#ifndef __DYNAMICAR_H__
#define __DYNAMICAR_H__
#include "stdafx.h"
#include "SdiObject.h"
#include "TypeInfo.h"
#include "MemAlloc.h"
 
namespace SDICW
{
    // Base Dynamic array
    class CDynamicAr : CSdiObject
    {
    public:
        // constructors
        CDynamicAr(void);
        virtual ~CDynamicAr(void);
 
        // methods
        sdVoid *GetData();
        const sdVoid *GetData() const;
 
        sdBool IsValidIndex(sdInt i) const;
        sdInt Count() const;
 
        sdVoid Insert(sdInt index, sdInt count, sdInt elementSize);
        sdVoid InsertZeroed(sdInt index, sdInt count, sdInt elementSize);
 
        sdInt Add(sdInt count, sdInt elementSize);
        sdInt AddZeroed(sdInt elementSize, sdInt count = 1);
 
        sdBool Shrink(sdInt elementSize);
 
        sdVoid Empty(sdInt elementSize, sdInt slack = 0);
 
        sdVoid Swap(sdInt elemA, sdInt elemB, sdInt elementSize);
 
        sdBool Remove(sdInt index, sdInt count, sdInt elementSize);
    protected:
        // reallocates the memory space on m_data
        sdVoid ReAllocate(sdInt elementSize);
        CDynamicAr(sdInt inNum, sdInt elementSize);
 
        // vars
        sdVoid *m_data; // memory space where we store the elements
        sdInt m_arrayNum; // number of elements in array
        sdInt m_arrayMax; // array capacity
    };
 
    typedef CDynamicAr ParentClass;
 
    // Dynamic array with template
    template<class _T> class TDynamicAr : public CDynamicAr
    {
    public:
        typedef _T ElementType;
 
        TDynamicAr() : ParentClass()
        {
        }
 
        TDynamicAr(sdInt num) : ParentClass(num, sizeof(ElementType)), m_iterator(NULL)
        {
        }
 
        TDynamicAr(const TDynamicAr &another)
            : ParentClass(another.m_arrayNum, sizeof(ElementType)), m_iterator(NULL)
        {
            // if its class type
            if(TTypeInfo<ElementType>::IsDestructorNeeded())
            {
                m_arrayNum = 0;
                for(int i = 0; i < another.Count(); i++)
                {
                    new(*this)ElementType(another[i]);
                }
            }
            else if(sizeof(ElementType) != 1) // if its not class type
            {
                for(int i = 0; i < m_arrayNum; i++)
                {
                    (*this)[i] = another[i];
                }
            }
            else // in another case copy the whole thing, we don't care
            {
                memcpy(&(*this)[0], &another[0], m_arrayNum * sizeof(ElementType));
            }
        }
 
        ~TDynamicAr()
        {
            Remove(0, m_arrayNum);
        }
 
        // operator overloads
 
        ElementType& operator[](sdInt i)
        {
            return ((ElementType *)m_data)[i];
        }
 
        const ElementType& operator[](sdInt i) const
        {
            return ((ElementType *)m_data)[i];
        }
 
        // concatenate with another dynamic array. e.g  arrayVar1 + arrayVar2
        TDynamicAr& operator+(const TDynamicAr& another)
        {
            if(this != &another)
            {
                for(sdInt i = 0; i < another.Count(); i++)
                {
                    new(*this)ElementType(another[i]);
                }
            }
 
            return *this;
        }
 
        TDynamicAr& operator+=(const TDynamicAr& another)
        {
            if(this != &another)
            {
                *this = *this + another;
            }
 
            return *this;
        }
 
        TDynamicAr& operator=(const TDynamicAr& another)
        {
            if(this != &another)
            {
                Empty(another.Count());
 
                for(sdInt i = 0; i < another.Count(); i++)
                {
                    new(*this)ElementType(another[i]);
                }
            }
 
            return *this;
        }
 
        // methods
 
        sdInt AddItem(const ElementType& element)
        {
            new(*this) ElementType(element);
            return Count() - 1; // return the index of the element
        }
 
        sdInt AddZeroed(sdInt count = 1)
        {
            return ParentClass::AddZeroed(sizeof(ElementType), count);
        }
 
        sdInt Add(sdInt count = 1)
        {
            return ParentClass::Add(count, sizeof(ElementType));
        }
 
        sdInt AddUnique(const ElementType& element)
        {
            for(int i = 0; i < m_arrayNum; i++)
            {
                // if its already in the array, return its index
                if((*this)[i] == element)
                {
                    return i;
                }
            }
 
            return AddItem(element);
        }
 
        sdVoid InsertItem(const ElementType& element, sdInt index)
        {
            sdInt idx = Insert(index);
            (*this)[idx] = element; // todo: debug this
        }
 
        sdVoid Insert(sdInt index, sdInt count = 1)
        {
            return ParentClass::Insert(index, count, sizeof(ElementType));
        }
 
        sdVoid InsertZeroed(sdInt index, sdInt count = 1)
        {
            return ParentClass::InsertZeroed(index, count, sizeof(ElementType));
        }
 
        ElementType Pop()
        {
            ElementType result = ((ElementType *)m_data)[m_arrayNum - 1];
            Remove(m_arrayNum - 1);
            return result;
        }
 
        ElementType& Last(sdInt c = 0)
        {
            return ((ElementType *)m_data)[m_arrayNum - count - 1];
        }
 
        const ElementType& Last(sdInt c = 0) const
        {
            return ((ElementType *)m_data)[m_arrayNum - count - 1];
        }
 
        sdVoid Shrink()
        {
            ParentClass::Shrink(sizeof(ElementType));
        }
 
        sdBool FindItem(const ElementType& item, __out sdInt& index) const
        {
            for(index = 0; index < m_arrayNum; index++)
            {
                if((*this)[index] == item)
                    return TRUE;
            }
 
            return FALSE;
        }
        sdInt FindItemIndex(const ElementType& item) const
        {
            for(sdInt index = 0; index < m_arrayNum; index++)
            {
                if((*this)[index] == item)
                    return index;
            }
 
            return INDEX_NONE;
        }
 
        sdBool Contains(const ElementType& item) const
        {
            return (FindItemIndex(item) != INDEX_NONE);
        }
 
        sdBool Remove(sdInt index, sdInt count = 1)
        {
            // if its class type, then we need to call its destructor
            if(TTypeInfo<ElementType>::IsDestructorNeeded())
            {
                for(sdInt i = index; i < index + count; i++ )
                {
                    (&(*this)[i])->~ElementType();
                }
            }
 
            return ParentClass::Remove(index, count, sizeof(ElementType));
        }
 
        sdBool Remove(const ElementType& element)
        {
            sdInt idx = FindItemIndex(element);
            return Remove(idx);
        }
 
        sdBool Empty(sdInt slack = 0)
        {
            if(TTypeInfo<ElementType>::IsDestructorNeeded())
            {
                for(sdInt i = 0; i < m_arrayNum; i++ )
                {
                    (&(*this)[i])->~ElementType();
                }
            }
 
            return ParentClass::Empty(sizeof(ElementType), slack);
        }
 
        sdVoid SwapItems(sdInt indexA, sdInt indexB)
        {
            ParentClass::Swap(indexA, indexB, sizeof(ElementType));
        }
 
        class Iterator
        {
        public:
            // constructor
            Iterator(TDynamicAr<ElementType>& inArray)
            {
                ++*this;
            }
 
            // operator overloads
 
            sdVoid operator++()
            {
                return m_array[m_index];
            }
 
            ElementType& operator*()
            {
                return m_array[m_index];
            }
 
            ElementType* operator->()
            {
                return &m_array[m_index];
            }
 
            operator sdBool() const
            {
                return m_index < m_array.Count();
            }
 
            sdVoid RemoveCurrent()
            {
                m_array.Remove(--m_index);
            }
 
            ElementType& GetCurrent() const
            {
                return m_index;
            }
 
            sdInt GetIndex() const
            {
                return m_array[m_index];
            }
 
            ElementType& GetNext() const
            {
                return m_array[m_index < m_array.Count() - 1 ? m_index + 1 : 0];
            }
            ElementType& GetPrev() const
            {
                return m_array[m_index ? m_index - 1 : m_array.Count() - 1];
            }
        private:
            TDynamicAr<ElementType>& m_array;
            sdInt m_index;
        };
 
        Iterator& GetIterator() const
        {
            if(m_iterator == NULL || !m_iterator)
            {
                m_iterator = new Iterator(this);
            }
 
            return m_iterator;
        }
    private:
        Iterator *m_iterator;
    };
 
    template<class T> sdVoid* operator new(size_t size, TDynamicAr<T>& ar)
    {
        int index = ar.CDynamicAr::Add(1, sizeof(T));
        return &ar[index];
    }
    template<class T> sdVoid* operator new(size_t size, TDynamicAr<T>& ar, sdInt index)
    {
        ar.CDynamicAr::Insert(index, 1, sizeof(T));
        return &ar[index];
    }
 
    // array exchanger
    template<class T> sdVoid ExchangeArray(TDynamicAr<T>& elemA, TDynamicAr<T>& elemB)
    {
        appMemorySwap(&elemA, &elemB, sizeof(CDynamicAr));
    }
}
#endif

Comments