#ifndef INCLUDE_NASTARRAY_H #define INCLUDE_NASTARRAY_H //----------------------------------------------------------------------------- // NastArray.h //----------------------------------------------------------------------------- // // Copyright (C) 1998 Technische Universitaet Muenchen, Germany // written by Bernhard Brueck // // This file is part of Nast++ // //----------------------------------------------------------------------------- // Die Klasse stellt eindimensionales Array zur Verfuehgung. // Die Elemente koennen ueber den operator( int,int) angesprochen werden. // mit Add koennen neue Werte hinzugefuegt werde. Das Array wird bei // Bedarf vergroessert. // Vorerst wird versucht den Speicher nur immer in der Groesse von // Zweierpotenzen zu belegen und bei Bedarf die Groesse des Arrays // zu verdoppeln. Falls diese Klasse intensiver gnutzt wird ist // es wahrscheinlich besser ein besseres Schema zu waehlen. //----------------------------------------------------------------------------- // Aenderungen: // #include "NastConfig.h" #include "NastDebug.h" template class CNastArray : public CNastObject { public: //------------------------------------------------------------------------- // Konstruktor + Destruktor //------------------------------------------------------------------------- CNastArray( int nSize = 0 ); virtual ~CNastArray(); // Destruktor CNastArray( const CNastArray & o ); // Copyconstr. const CNastArray& operator=( const CNastArray &o ); // Zuweisungsoperator //------------------------------------------------------------------------- // Zugriffsfunktionen //------------------------------------------------------------------------- void add( const T &ele ); // eine Element hinzufuegen void setSize( int nSize ); // Groesse des Arrays festlegen void setAll( const T &ele ); // alle Werte zuweisen int size() const; // Groesse des Arrays const T& operator[]( int i ) const; // rhs T& operator[]( int i ); // lhs //------------------------------------------------------------------------- // Debug //------------------------------------------------------------------------- // debugInfo gibt Information ueber den Zustand des Objekts aus // assertValid testet das Objekt auf Integritaet // virtual void assertValid() const; virtual void debugDump( CNastDumpContext &dumpContext ) const; private: //------------------------------------------------------------------------- // Hilfsunktionen //------------------------------------------------------------------------- int calcSize( int nSize ) const; // benoetigte Speichergroesse //------------------------------------------------------------------------- // Membervariablen //------------------------------------------------------------------------- T *m_arrData; // die eigentlichen Daten int m_nSize; // tatsaechliche Groesse int m_nSizeAll; // Groesse des allozierten Speicherplatzes }; //------------------------------------------------------------------------- // Implementation //------------------------------------------------------------------------- // Konstruktor unter der Angabe der Groesse des Arrays template CNastArray::CNastArray( int nSize /* =0 */ ) :m_arrData ( 0 ), m_nSize ( nSize ), m_nSizeAll( calcSize(nSize) ) { NAST_ASSERT( m_nSizeAll >0 ); m_arrData = new T[m_nSizeAll]; } // Copyconstr. template CNastArray::CNastArray( const CNastArray &other ) :CNastObject( other ), m_arrData ( 0 ), m_nSize ( other.m_nSize ), m_nSizeAll ( calcSize( other.m_nSize ) ) { NAST_ASSERT_VALID( &other ); m_arrData = new T[m_nSizeAll]; for( int i = 0; i < m_nSize; i++) m_arrData[i] = other.m_arrData[i]; } // Destruktor template CNastArray::~CNastArray() { NAST_ASSERT_VALID( this ); delete [] m_arrData; m_arrData = 0; m_nSizeAll = 0; m_nSize = 0; } // Zuweisungsoperator template const CNastArray& CNastArray::operator=( const CNastArray &other ) { NAST_ASSERT_VALID( this ); NAST_ASSERT_VALID( &other ); if( this != &other ) // keine Zuweisung auf sich selbst ? { CNastObject::operator=( other ); m_nSize = other.m_nSize; m_nSizeAll = calcSize( other.m_nSize ); delete [] m_arrData; m_arrData = new T[ m_nSizeAll ]; for( int i = 0; i < m_nSize; i++) m_arrData[i] = other.m_arrData[i]; } return *this; } // ---------------------------------------------------------------------------- // Debug // ---------------------------------------------------------------------------- template void CNastArray::assertValid() const { NAST_ASSERT( m_arrData ); // Speicher belegt ? NAST_ASSERT( m_nSizeAll > 0 ); // Es ist immer mind. ein Element belegt NAST_ASSERT( m_nSize >= 0 ); // keine negative Elementanzahl NAST_ASSERT( m_nSizeAll >= m_nSize ); // nie weniger belegt als benutzt wird } template void CNastArray::debugDump( CNastDumpContext &dumpContext ) const { CNastObject::debugDump( dumpContext ); dumpContext << "\t" << "CNastArray "; dumpContext << "\t" << "belegt:" << m_nSize << " "; dumpContext << "\t" << "reserviert:" << m_nSizeAll << "\n"; // ii statt i um einen Bug in g++2.7.2 zu umgehen for( int ii = 0; ii < size(); ii++) { dumpContext << "\t\t[" << ii << "] = "; dumpContext << operator[](ii) << "\n"; } } // ---------------------------------------------------------------------------- // Hilfsfunktionen // ---------------------------------------------------------------------------- // Berechnet die naechsthoehere Zweierpotenz fuer nSize template int CNastArray::calcSize( int nSize ) const { int nSizeAll = 1; while( nSizeAll < nSize ) nSizeAll *= 2; return nSizeAll; } // neue Groesse des Arrays festlegen template void CNastArray::setSize( int nSize ) { if( nSize > m_nSizeAll ) { // neue Groesse berechnen int nSizeAll = calcSize( nSize ); // und kopieren T *arrOldData = m_arrData; m_nSizeAll = nSizeAll; m_arrData = new T[m_nSizeAll]; // ii statt i um einen Bug in g++2.7.2 zu umgehen for( int ii = 0; ii< m_nSize; ii++) m_arrData[ii] = arrOldData[ii]; // alten Speicher freigeben delete [] arrOldData; } m_nSize = nSize; } // ---------------------------------------------------------------------------- // Memberfunktionen // ---------------------------------------------------------------------------- // alle Elemente im Array auf einen Wert setzen template void CNastArray::setAll( const T& element) { for( int i = 0; i < m_nSize; i++) m_arrData[i] = element; } // ein Element hinzufuegen template inline void CNastArray::add( const T &element ) { NAST_ASSERT_VALID( this ); if( m_nSize < m_nSizeAll ) // noch Platz vorhanden ? { m_arrData[m_nSize++] = element; } else { int i = m_nSize; setSize( i + 1); m_arrData[i] = element; } } // lesender Zugriff auf ein Element template inline const T& CNastArray::operator[]( int i ) const { NAST_ASSERT_VALID( this ); NAST_ASSERT_INDEX( i >= 0 ); NAST_ASSERT_INDEX( i < m_nSize ); return m_arrData[i]; } // schreibender Zugriff auf ein Element template inline T& CNastArray::operator[]( int i ) { NAST_ASSERT_VALID( this ); NAST_ASSERT_INDEX( i >= 0 ); NAST_ASSERT_INDEX( i < m_nSize ); return m_arrData[i]; } // Anzahl der Elemente im Array template inline int CNastArray::size() const { NAST_ASSERT_VALID( this ); return m_nSize; } #endif // INCLUDE_NASTARRAY_H