Listing 1: The underlying Array class


// Stephen O. Schulist - 29 October 1995

#ifndef _SOS_ARRAY_H
#define _SOS_ARRAY_H

#include "assert.h"
#include <iostream.h>

template<class T> class Array
{
public:

   Array(int length = 0);
   Array(int length, const T& value);
   Array(const Array<T>& array);
  ~Array();

  Array<T>& operator=(const Array<T>& array);

  int operator==(const Array<T>& array) const;
  int operator!=(const Array<T>& array) const;

  void NewLength(int length, const T& value = 0);

  int Length() const { return m_nLength; }

  const T& operator[](int index) const;
        T& operator[](int index);

private:

  int m_nLength;
  T*  m_pValue;
};

template<class T> inline Array<T>::Array(int length) :
  m_nLength(length)
{
  ASSERT( m_nLength >= 0 );

  m_pValue = new T[m_nLength];
}

template<class T> inline Array<T>::Array(int length, const T& value) :
  m_nLength(length)
{
  ASSERT( m_nLength >= 0 );
  m_pValue = new T[m_nLength];
  for ( int n = 0; n < m_nLength; n++ )
    m_pValue[n] = value;
}

template<class T> inline Array<T>::Array(const Array<T>& array) :
  m_nLength(array.m_nLength)
{
  ASSERT( m_nLength >= 0 );
  m_pValue = new T[m_nLength];
  for ( int n = 0; n < m_nLength; n++ )
    m_pValue[n] = array.m_pValue[n];
}

template<class T> inline Array<T>::~Array()
{
  delete [] m_pValue;
}

template<class T> inline Array<T>& Array<T>::operator=(const Array<T>& array)
{
  if ( this != &array )
  {
    delete [] m_pValue;

    m_nLength = array.m_nLength;

    m_pValue  = new T[m_nLength];
    for ( int n = 0; n < m_nLength; n++ )
    {
      m_pValue[n] = array.m_pValue[n];
    }
  }

  return *this;
}

template<class T> inline int Array<T>::operator==(const Array<T>& array) const
{
  int equal = ( m_nLength == array.m_nLength );
  for ( int n = 0; equal && ( n < m_nLength ); n++ )
  {
    equal = ( m_pValue[n] == array.m_pValue[n] );
  }

  return equal;
}

template<class T> inline int Array<T>::operator!=(const Array<T>& array) const
{
  return !operator==(array);
}

template<class T> inline void Array<T>::NewLength(int length, const T& value)
{
  T* pTmp = new T[length];
  const int limit = ( length < m_nLength ) ? length : m_nLength;
  for ( int n = 0; n < limit; n++ )
  {
    pTmp[n] = m_pValue[n];
  }
  for ( int n = limit; n < length; n++ )
  {
    pTmp[n] = value;
  }
  delete [] m_pValue;
  m_nLength = length;
  m_pValue  = pTmp;
}

template<class T> inline const T& Array<T>::operator[](int index) const
{
  ASSERT( index >= 0 );
  ASSERT( index < m_nLength );

  return m_pValue[index];
}

template<class T> inline T& Array<T>::operator[](int index)
{
  ASSERT( index >= 0 );
  ASSERT( index < m_nLength );
  return m_pValue[index];
}

template<class T> inline ostream& operator<<(
  ostream& stream, const Array<T>& array)
{
  for ( int n = 0; n < array.Length(); n++ )
  {
    stream << array[n] << endl;
  }
  return stream;
}

#endif