#ifndef PLIST_C #define PLIST_C //***************************************************************************** // // PList.C // //***************************************************************************** // // Copyright (C) 1996 // // Ronald A. MacCracken // Graduate Student // Computer Science Department // University of California // Davis, CA 95616 // // Permission is granted to use at your own risk and // distribute this software in source and binary forms // provided the above copyright notice and this paragraph // are preserved on all copies. This software is provided // "as is" with no express or implied warranty. // //***************************************************************************** #include #include "PListIterator.h" #include "PList.h" // // Constructors and Destructors // template PList :: PList ( void ) : first ( NULL ) , last ( NULL ) , length ( 0 ) { } template PList :: PList ( int s ) : first ( NULL ) , last ( NULL ) , length ( 0 ) { } template PList :: PList ( TYPE* t ) : first ( NULL ) , last ( NULL ) , length ( 0 ) { assert ( t != NULL ) ; first = last = new PListElement ( t ) ; length = 1 ; } template PList :: PList ( const PList& l ) { Copy ( l ) ; } template PList :: ~PList ( void ) { Delete ( ) ; } // // Private Member Functions // template void PList :: Copy ( const PList& l ) { length = l.length ; if ( l.Get_Length ( ) == 0 ) { first = last = NULL ; return ; } PListElement* element = l.first ; first = last = element->Get_Copy ( ) ; while ( element != l.last ) { element = element->Get_Next ( ) ; last->Set_Next ( element->Get_Copy ( ) ) ; last = last->Get_Next ( ) ; } } template void PList :: Reset ( void ) { PListElement* element = first ; while ( element != NULL ) { element->Set_Data ( NULL ) ; element = element->Get_Next ( ) ; } Delete ( ) ; } template void PList :: Delete ( void ) { delete first ; first = last = NULL ; length = 0 ; } // // Protected Member Functions // template PListElement* PList :: Find_Previous ( int x ) { assert ( first != NULL ) ; // test for special cases if ( ( x < 0 ) || ( x >= length ) ) { if ( x == FIRST ) x = 0 ; else if ( x == LAST ) x = length - 1 ; else assert ( ( x >= 0 ) && ( x < length ) ) ; } // if looking for first element, return NULL if ( x == 0 ) return ( NULL ) ; // look for i-1 element PListElement* element = first ; for ( int i = 0 ; i < x - 1 ; ++i ) element = element->Get_Next ( ) ; return ( element ) ; } template PListElement* PList :: Find_Previous ( TYPE* t ) { assert ( first != NULL ) ; assert ( t != NULL ) ; PListElement* previous = NULL ; PListElement* element = first ; while ( element != NULL ) { if ( element->Compare_Data ( t ) ) return ( previous ) ; previous = element ; element = element->Get_Next ( ) ; } assert ( 0 ) ; return ( NULL ) ; } template const TYPE* PList :: Find_Element ( const int x ) const { assert ( first != NULL ) ; // test for special cases if ( ( x < 0 ) || ( x >= length ) ) { if ( x == FIRST ) return ( first->Get_Data ( ) ) ; else if ( x == LAST ) return ( last->Get_Data ( ) ) ; else assert ( ( x >= 0 ) && ( x < length ) ) ; } // look for ith element PListElement* element = first ; for ( int i = 0 ; i < x ; i++ ) element = element->Get_Next ( ) ; return ( element->Get_Data ( ) ) ; } template void PList :: Insert_Element ( PListElement* previous , TYPE* new_data ) { assert ( new_data != NULL ) ; PListElement* new_element = new PListElement ( new_data ) ; if ( previous == NULL ) { new_element->Set_Next ( first ) ; first = new_element ; } else { PListElement* next = previous->Get_Next ( ) ; previous->Set_Next ( new_element ) ; new_element->Set_Next ( next ) ; } ++length ; } template void PList :: Insert_List ( PListElement* previous , const PList& new_list ) { if ( new_list.Get_Length ( ) == 0 ) return ; // make copy of list PList l = new_list ; // insert new_list into this list PListElement* next_element ; if ( previous == NULL ) { next_element = first ; first = l.first ; } else { next_element = previous->Get_Next ( ) ; previous->Set_Next ( l.first ) ; } l.last->Set_Next ( next_element ) ; length += l.Get_Length ( ) ; // make sure new_list is not deleted l.first = l.last = NULL ; } template void PList :: Remove_Element ( PListElement* prev , const int d ) { assert ( first != NULL ) ; PListElement* curr ; if ( prev == NULL ) curr = first ; else curr = prev->Get_Next ( ) ; // make adjustments in list if ( curr == first ) { first = first->Get_Next ( ) ; if ( curr == last ) last = NULL ; } else if ( curr == last ) { prev->Set_Next ( NULL ) ; last = prev ; if ( curr == first ) curr = NULL ; } else prev->Set_Next ( curr->Get_Next ( ) ) ; // delete curr from list curr->Set_Next ( NULL ) ; if ( d ) delete curr ; --length ; } template void PList :: Output ( ostream& co ) const { co << "List\n" ; co << " Length: " << Get_Length ( ) << "\n" ; co << " Data:\n" ; co << " {\n" ; for ( PListIterator j = *this ; ! j.Is_Done ( ) ; ++j ) co << " " << *j.Get_Current ( ) << "\n" ; co << " }" << endl ; } template void PList :: Input ( istream& ci ) { TYPE* t ; STring s ; char c ; int l ; Delete ( ) ; ci >> s ; ci >> s >> l ; // read length of list ci >> s >> c ; // read data string and first bracket for ( int i = 0 ; i < l ; i++ ) // read in elements { t = new TYPE ; ci >> *t ; Append ( t ) ; } ci >> c ; } // // Public Member Functions // template PList& PList :: operator= ( const PList& l ) { if ( this == &l ) return ( *this ) ; Delete ( ) ; Copy ( l ) ; return ( *this ) ; } template PList& PList :: operator, ( TYPE* elmt ) { Append ( elmt ) ; return ( *this ) ; } template const TYPE* PList :: operator[] ( const int x ) const { return ( Find_Element ( x ) ) ; } template TYPE* PList :: operator[] ( const int x ) { return ( (TYPE*) Find_Element ( x ) ) ; } template void PList :: Append ( TYPE* t ) { assert ( t != NULL ) ; PListElement* element = new PListElement ( t ) ; if ( first == NULL ) first = last = element ; else { last->Set_Next ( element ) ; last = element ; } ++length ; } template void PList :: Append ( const PList& l ) { if ( first == NULL ) { operator= ( l ) ; return ; } for ( PListIterator i = l ; ! i.Is_Done ( ) ; ++i , ++length ) { last->Set_Next ( new PListElement ( i.Get_Current ( ) ) ) ; last = last->Get_Next ( ) ; } } template void PList :: Insert ( const int x , TYPE* new_data ) { if ( length == 0 ) Append ( new_data ) ; else Insert_Element ( Find_Previous ( x ) , new_data ) ; } template void PList :: Insert ( const int x , const PList& new_list ) { if ( length == 0 ) Append ( new_list ) ; else Insert_List ( Find_Previous ( x ) , new_list ) ; } template void PList :: Insert ( TYPE* t , TYPE* new_data ) { if ( length == 0 ) Append ( new_data ) ; else Insert_Element ( Find_Previous ( t ) , new_data ) ; } template void PList :: Insert ( TYPE* t , const PList& new_list ) { if ( length == 0 ) Append ( new_list ) ; else Insert_List ( Find_Previous ( t ) , new_list ) ; } template void PList :: Replace ( const int x , TYPE* new_data ) { assert ( new_data != NULL ) ; PListElement* element = Find_Previous ( x ) ; if ( element == NULL ) element = first ; else element = element->Get_Next ( ) ; element->Set_Data ( new_data ) ; } template void PList :: Replace ( TYPE* t , TYPE* new_data ) { assert ( new_data != NULL ) ; PListElement* element = Find_Previous ( t ) ; if ( element == NULL ) element = first ; else element = element->Get_Next ( ) ; element->Set_Data ( new_data ) ; } template void PList :: Extract ( const int x ) { if ( x == EXTRACT_ALL ) Reset ( ) ; else Remove_Element ( Find_Previous ( x ) , 0 ) ; } template void PList :: Extract ( TYPE* t ) { Remove_Element ( Find_Previous ( t ) , 0 ) ; } template void PList :: Remove ( const int x ) { if ( x == REMOVE_ALL ) Delete ( ) ; else Remove_Element ( Find_Previous ( x ) , 1 ) ; } template void PList :: Remove ( TYPE* t ) { Remove_Element ( Find_Previous ( t ) , 1 ) ; } // // Friend Functions // template ostream& operator<< ( ostream& co , const PList& l ) { l.Output ( co ) ; return ( co ) ; } template istream& operator>> ( istream& ci , PList& l ) { l.Input ( ci ) ; return ( ci ) ; } // // Helper Functions // template int Compare_Lists ( const PList& l1 , const PList& l2 ) { for ( PListIterator i = l1 , j = l2 ; ! i.Is_Done ( ) ; ++i , ++j ) { if ( j.Is_Done ( ) ) return ( 0 ) ; if ( ! ( *i.Get_Current ( ) == *j.Get_Current ( ) ) ) return ( 0 ) ; } if ( j.Is_Done ( ) ) return ( 1 ) ; return ( 0 ) ; } template int Search_List ( const PList& l , const TYPE& data , int& index ) { index = 0 ; for ( PListIterator i = l ; ! i.Is_Done ( ) ; ++i ) { if ( *i.Get_Current ( ) == data ) return ( 1 ) ; ++index ; } return ( 0 ) ; } template int Search_List ( const PList& l , const TYPE* data , int& index ) { index = 0 ; for ( PListIterator i = l ; ! i.Is_Done ( ) ; ++i ) { if ( i.Get_Current ( ) == data ) return ( 1 ) ; ++index ; } return ( 0 ) ; } #endif