Click here to Skip to main content
15,895,830 members
Articles / Desktop Programming / MFC

A Java Language IDE

Rate me:
Please Sign up or sign in to vote.
4.33/5 (26 votes)
13 May 2004CPOL3 min read 80.7K   3.4K   41  
This is a partially implemented IDE for the Java platform.
template<typename TYPE>
class CLinkedArray
{
    struct _arraySegment
    {
      CArray<TYPE,TYPE> m_arrSegData;
	  _arraySegment     *m_pNext;
	  _arraySegment     *m_pPrev;

	  _arraySegment(long nSize)
	  {
        m_arrSegData.SetSize(nSize);
		m_pNext = NULL;m_pPrev = NULL;
	  }
    };

	long           m_nGrowBy;
	long           m_nActualLength;
	long           m_nArrayLength;
	_arraySegment* m_pHeadNode;
	_arraySegment* m_pTailNode;
public:
	CLinkedArray();
	CLinkedArray(long nInitSize);
	virtual ~CLinkedArray();

	//attributes
	void SetSize(long nNewSize,long nGrowBy = -1);
	long GetCount();
	long GetSize();
	long GetUpperBound();
	bool IsEmpty();

	//operations
	void FreeExtra();
	void RemoveAll();

	//element access
	TYPE& ElementAt(long nIndex);
	TYPE& GetAt(long nIndex);
	TYPE* GetData();
	void  SetAt(long nIndex,TYPE newItem);

	//growing array
	long Add(TYPE data);
	long Append(CLinkedArray& arrSrc);
	void Copy(CLinkedArray& arrSrc);
	void SetAtGrow(long nIndex, TYPE newItem);

	//insertion\removal
    void InsertAt(long nIndex,TYPE newItem,long nCount = 1);
    void InsertAt(long nStartIndex,CLinkedArray* pNewArray);
    void RemoveAt(long nIndex,long nCount = 1);

	//operator
	TYPE& operator[](long nIndex);
};

template<typename TYPE>
CLinkedArray<TYPE>::CLinkedArray()
{
  m_pHeadNode     = NULL;
  m_pTailNode     = NULL;
  m_nArrayLength  = 0;
  m_nActualLength = 0;
  m_nGrowBy       = 0;
}


template<typename TYPE>
CLinkedArray<TYPE>::CLinkedArray(long nInitSize)
{
  m_pHeadNode     = new _arraySegment(nInitSize);
  m_pTailNode     = m_pHeadNode;
  m_nArrayLength  = 0;
  m_nActualLength = nInitSize;
  m_nGrowBy       = 0;
}

template<typename TYPE>
CLinkedArray<TYPE>::~CLinkedArray()
{


}

template<typename TYPE>
void CLinkedArray<TYPE>::SetSize(long nNewSize,long nGrowBy /*= -1*/)
{
  if(nGrowBy != -1)
    m_nGrowBy = nGrowBy;

  if(nNewSize == 0)//remove all objects
  {
	RemoveAll();
    m_nArrayLength = 0;
  }
  else
  if(m_pHeadNode == NULL)//array empty
  {
    m_pHeadNode     = new _arraySegment(nNewSize);
    m_pTailNode     = m_pHeadNode;
    m_nArrayLength  = 0;
    m_nActualLength = nNewSize;
  }
  else
  if(nNewSize<=m_nActualLength)
	m_nArrayLength = nNewSize;
  else
  {
		// otherwise, grow array
	  int nGrowBy = m_nGrowBy;
	  if(nGrowBy == 0)
	  {
		//heuristically determine growth when nGrowBy == 0
		//(this avoids heap fragmentation in many situations)
		nGrowBy = m_nArrayLength / 8;
		nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
	  }

      //allocate new segment
	  CLinkedArray::_arraySegment* pArraySeg = new 
		  CLinkedArray::_arraySegment(nGrowBy);

	  if(m_pTailNode != NULL)
	    m_pTailNode->m_pNext =  pArraySeg;

      pArraySeg->m_pPrev   =  m_pTailNode;
	  m_pTailNode          =  pArraySeg;
      TYPE* pData          =  pArraySeg->m_arrSegData.GetData();
	  long  nCapacity      =  sizeof(pData);
      m_nActualLength      += nCapacity;
  }
}


template<typename TYPE>
long CLinkedArray<TYPE>::GetCount()
{
   return m_nArrayLength;
} 


template<typename TYPE>
long CLinkedArray<TYPE>::GetSize()
{
  return m_nArrayLength;
}


template<typename TYPE>
long CLinkedArray<TYPE>::GetUpperBound()
{
  return m_nArrayLength;
}

template<typename TYPE>
bool CLinkedArray<TYPE>::IsEmpty()
{
  return (m_nArrayLength == 0);
}

//operations
template<typename TYPE>
void CLinkedArray<TYPE>::FreeExtra()
{
  m_pTailNode->m_arrSegData.FreeExtra();
}


template<typename TYPE>
void CLinkedArray<TYPE>::RemoveAll()
{
	for(CLinkedArray::_arraySegment* pCur = m_pHeadNode; pCur != NULL;)
	{
      pCur->m_arrSegData.RemoveAll();
      CLinkedArray::_arraySegment* pNext = pCur->m_pNext;
	  delete pCur;
	  pCur = pNext;
	}
	m_pHeadNode     = NULL;
	m_pTailNode     = NULL;
	m_nArrayLength  = 0;
	m_nActualLength = 0;
}
											 
//element access
template<typename TYPE>
TYPE& CLinkedArray<TYPE>::ElementAt(long nIndex)
{
	ASSERT(nIndex<GetCount());

	long nAccuCount = 0;
	for(CLinkedArray::_arraySegment* pCur = m_pHeadNode; pCur != NULL; 
	                                          pCur = pCur->m_pNext)
	{
       nAccuCount += pCur->m_arrSegData.GetSize();
	   if(nAccuCount>nIndex)
		   break;
	}
    int nSegIndex = nIndex-(nAccuCount-pCur->m_arrSegData.GetSize());
    return pCur->m_arrSegData[nSegIndex];
}

template<typename TYPE>
TYPE& CLinkedArray<TYPE>::GetAt(long nIndex)
{
  return ElementAt(nIndex);
}


template<typename TYPE>
TYPE* CLinkedArray<TYPE>::GetData()
{
  return (TYPE)NULL;
}

template<typename TYPE>
void  CLinkedArray<TYPE>::SetAt(long nIndex,TYPE newItem)
{
   ASSERT(nIndex<GetCount());
   InsertAt(nIndex,newItem);
}

//growing array
template<typename TYPE>
long CLinkedArray<TYPE>::Add(TYPE newElement)
{
  int nIndex = m_nArrayLength;
  SetAtGrow(nIndex, newElement);
  return nIndex;
}

template<typename TYPE>
long CLinkedArray<TYPE>::Append(CLinkedArray& arrSrc)
{
  return 0;
}

template<typename TYPE>
void CLinkedArray<TYPE>::Copy(CLinkedArray& arrSrc)
{

}

template<typename TYPE>
void CLinkedArray<TYPE>::SetAtGrow(long nIndex, TYPE newElement)
{
	//ASSERT_VALID(this);
	ASSERT(nIndex >= 0);

	if(nIndex >= m_nArrayLength)
		SetSize(nIndex+1, -1);

	long nAccuCount = 0;
	for(CLinkedArray::_arraySegment* pCur = m_pHeadNode; pCur != NULL; 
	                                          pCur = pCur->m_pNext)
	{
       nAccuCount += pCur->m_arrSegData.GetSize();
	   if(nAccuCount>nIndex) break;
	}


    int nSegIndex = nIndex-(nAccuCount-pCur->m_arrSegData.GetSize());
	pCur->m_arrSegData[nSegIndex] = newElement;
}

//insertion\removal
template<typename TYPE>
void CLinkedArray<TYPE>::InsertAt(long nIndex,TYPE newItem,long nCount /*= 1*/)
{
	ASSERT(nIndex<GetCount());

	long nAccuCount = 0;
	for(CLinkedArray::_arraySegment* pCur = m_pHeadNode; pCur != NULL; 
	                                          pCur = pCur->m_pNext)
	{
       nAccuCount += pCur->m_arrSegData.GetSize();
	   if(nAccuCount>nIndex) break;
	}


    int nSegIndex = nIndex-(nAccuCount-pCur->m_arrSegData.GetSize());

    TYPE* pData = pCur->m_arrSegData.GetData();
	long  nCapacity  = sizeof(pData);
	long  nSize      = pCur->m_arrSegData.GetSize();
	long  nFreeSlots = nCapacity - nSize;

	if(nCount>nFreeSlots)
	{            
      pCur->m_arrSegData.InsertAt(nSegIndex,newItem,nFreeSlots);

	  m_nArrayLength += nFreeSlots;
	  long nExtra     = nCount-nFreeSlots;

	  for(int I=0; I<nExtra; I++)//allocate new segment and add remaining items
		  Add(newItem);
	}
	else
	{
	  pCur->m_arrSegData.InsertAt(nSegIndex,newItem,nCount);
	  m_nArrayLength += nCount;
	}
}

template<typename TYPE>
void CLinkedArray<TYPE>::InsertAt(long nStartIndex,CLinkedArray* pNewArray)
{
    ASSERT(pNewArray != NULL);
}

template<typename TYPE>
void CLinkedArray<TYPE>::RemoveAt(long nIndex,long nCount /*= 1*/)
{
	ASSERT(nIndex<GetCount());

	long nAccuCount = 0;
	for(CLinkedArray::_arraySegment* pCur = m_pHeadNode; pCur != NULL; 
	                                          pCur = pCur->m_pNext)
	{
       nAccuCount += pCur->m_arrSegData.GetSize();
	   if(nAccuCount>nIndex) break;
	}


	long  nSize      = pCur->m_arrSegData.GetSize();
    int nSegIndex = nIndex-(nAccuCount-nSize);

	if(nCount>=nSize)
	{
	  int nDelCount = nCount;
	  for(pCur;pCur != NULL;)
	  {        
        nSize            = pCur->m_arrSegData.GetSize();
        TYPE* pData      = pCur->m_arrSegData.GetData();
	    long  nCapacity  = sizeof(pData);

        if(nDelCount>=nSize)
		{
          nDelCount       -= nSize;
          nAccuCount      -= nSize;
		  m_nArrayLength  -= nSize;
		  m_nActualLength -= nCapacity;//remove this nodes's size
	      pCur->m_arrSegData.RemoveAll();
		}
		else
		if(nDelCount>0)
		{
		   nSegIndex        = nIndex-nAccuCount;
           m_nArrayLength  -= nDelCount;
           pCur->m_arrSegData.RemoveAt(nSegIndex,nDelCount);
           break;
		}
		else
		break;

        CLinkedArray::_arraySegment* pPrev = pCur->m_pPrev;
	    delete pCur;
	    pCur = pPrev;
	  }
	}
	else
	{
	  m_nArrayLength  -= nCount;
	  pCur->m_arrSegData.RemoveAt(nSegIndex,nCount);
	}
}

//operator
template<typename TYPE>
TYPE& CLinkedArray<TYPE>::operator[](long nIndex)
{
  return ElementAt(nIndex);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
biography? I am not that old yet.

Comments and Discussions