/////////////////////////////////////////////////////////////////////////////// // // // This file is part of ModelBlocks. Copyright 2009, ModelBlocks developers. // // // // ModelBlocks is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // ModelBlocks is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with ModelBlocks. If not, see . // // // // ModelBlocks developers designate this particular file as subject to // // the "Moses" exception as provided by ModelBlocks developers in // // the LICENSE file that accompanies this code. // // // /////////////////////////////////////////////////////////////////////////////// #ifndef _NL_LIST_ ////////////////////////////////////////////////////////////// #define _NL_LIST_ ////////////////////////////////////////////////////////////// #include #define Listed(x) ListedObject //////////////////////////////////////////////////////////////////////////////// // // Container macros // //////////////////////////////////////////////////////////////////////////////// // Standard loop... #define foreach(p,c) for ( p=(c).getNext(NULL); p!=NULL; p=(c).getNext(p) ) // True unless proven false... #define setifall(y,p,c,x) for ( p=(c).getNext(NULL), y=true; p!=NULL && y; y &= (x), p=(c).getNext(p) ) // False unless proven true... #define setifexists(y,p,c,x) for ( p=(c).getNext(NULL), y=false; p!=NULL && !y; y |= (x), p=(c).getNext(p) ) //////////////////////////////////////////////////////////////////////////////// template class Ptr { private: T* ptObj ; public: Ptr ( ) { ptObj=NULL; } Ptr ( T* pt ) { ptObj=pt; } Ptr ( T& t ) { ptObj=&t; } Ptr ( const Ptr& pt ) { ptObj=pt.ptObj; } bool operator> ( const Ptr& pt ) const { return(ptObj>pt.ptObj); } bool operator< ( const Ptr& pt ) const { return(ptObj= ( const Ptr& pt ) const { return(ptObj>=pt.ptObj); } bool operator<= ( const Ptr& pt ) const { return(ptObj<=pt.ptObj); } bool operator== ( const Ptr& pt ) const { return(ptObj==pt.ptObj); } bool operator!= ( const Ptr& pt ) const { return(ptObj!=pt.ptObj); } Ptr& operator= ( const Ptr& pt ) { ptObj=pt.ptObj; return *this; } T& operator* ( ) const { return *ptObj; } T* operator-> ( ) const { return ptObj; } } ; //////////////////////////////////////////////////////////////////////////////// template class ListedObject ; template class List { private: ListedObject* plotLast ; public: typedef ListedObject* iterator; typedef const ListedObject* const_iterator; // Constructor and destructor methods... List ( ) ; List ( const T& ) ; List ( const List& ) ; List ( const List&, const List& ) ; ~List ( ) ; // Overloaded operators... List& operator= ( const List& ) ; List& operator+= ( const List& ) ; bool operator== ( const List& ) const ; bool operator!= ( const List& ) const ; // Specification methods... void clear ( ) ; T& insert ( Listed(T)* ) ; void remove ( Listed(T)* ) ; T& add ( ) ; T& push ( ) ; void pop ( ) ; Listed(T)* setFirst ( ) ; Listed(T)* setNext ( Listed(T)* ) ; // Extraction methods... const_iterator begin ( ) const { return getNext(NULL); } const_iterator end ( ) const { return NULL; } iterator& operator++ ( ) { *this=getNext(*this); return *this; } int getCard ( ) const ; Listed(T)* getFirst ( ) const ; Listed(T)* getSecond( ) const ; Listed(T)* getLast ( ) const ; Listed(T)* getNext ( const Listed(T)* ) const ; bool contains ( const T& ) const ; bool isEmpty ( ) const ; /* // Input / output methods... */ /* friend IStream operator>> ( pair*> is_x, const char* psDlm ) { */ /* IStream& is = is_x.first; */ /* List& x = *is_x.second; */ /* if (IStream()!=is) */ /* is = pair(is,&x.add())>>psDlm; */ /* return is; */ /* } */ } ; //////////////////////////////////////////////////////////////////////////////// template class ListedObject : public T { friend class List ; private: ListedObject* plotNext ; public: const ListedObject* next ( ) const { return plotNext; } ListedObject ( ) { plotNext = NULL; } ListedObject ( const ListedObject& lot ) { T::operator=(lot); } ListedObject& operator= ( const ListedObject& lot ) { T::operator=(lot); return(*this); } operator T() { return *this; } } ; //////////////////////////////////////////////////////////////////////////////// template List::List ( ) { plotLast = NULL ; } //////////////////////////////////////////////////////////////////////////////// template List::List ( const T& t ) { plotLast = NULL ; add() = t ; } //////////////////////////////////////////////////////////////////////////////// template List::List ( const List& lt ) { ListedObject* pt ; plotLast = NULL ; foreach ( pt, lt ) add() = *pt ; } //////////////////////////////////////////////////////////////////////////////// template List::List ( const List& lt1, const List& lt2 ) { ListedObject* pt ; plotLast = NULL ; foreach ( pt, lt1 ) add() = *pt ; foreach ( pt, lt2 ) add() = *pt ; } //////////////////////////////////////////////////////////////////////////////// template List::~List ( ) { clear(); } //////////////////////////////////////////////////////////////////////////////// template void List::clear ( ) { ListedObject* plot ; ListedObject* plot2 ; if ( NULL != (plot = plotLast) ) do { plot2 = plot->plotNext ; ////fprintf(stderr,"list::destr %x\n",plot); delete plot ; } while ( plotLast != (plot = plot2) ) ; plotLast = NULL ; } //////////////////////////////////////////////////////////////////////////////// template List& List::operator= ( const List& lt ) { Listed(T)* pt ; this->~List ( ) ; plotLast = NULL ; foreach ( pt, lt ) add() = *pt ; return *this ; } //////////////////////////////////////////////////////////////////////////////// template List& List::operator+= ( const List& lt ) { Listed(T)* pt ; foreach ( pt, lt ) add() = *pt ; return *this ; } //////////////////////////////////////////////////////////////////////////////// template bool List::operator== ( const List& lt ) const { Listed(T)* pt1 ; Listed(T)* pt2 ; for ( pt1 = getNext(NULL), pt2 = lt.getNext(NULL); pt1 != NULL && pt2 != NULL ; pt1 = getNext(pt1), pt2 = lt.getNext(pt2) ) if ( !(*pt1 == *pt2) ) return false ; return ( pt1 == NULL && pt2 == NULL ) ; } //////////////////////////////////////////////////////////////////////////////// template bool List::operator!= ( const List& lt ) const { return !(*this == lt) ; } //////////////////////////////////////////////////////////////////////////////// template T& List::insert ( Listed(T)* plotPrev ) { ListedObject* plot = new ListedObject ; ////fprintf(stderr,"list::const %x\n",plot); if ( NULL != plotPrev ) { plot->plotNext = plotPrev->plotNext ; plotPrev->plotNext = plot ; if ( plotLast == plotPrev ) plotLast = plot ; } else if ( NULL != plotLast ) { plot->plotNext = plotLast->plotNext ; plotLast->plotNext = plot ; } else { plot->plotNext = plot ; plotLast = plot ; } return *plot ; } //////////////////////////////////////////////////////////////////////////////// /* DON'T KNOW WHY THIS DOESN'T WORK template void List::remove ( Listed(T)* plot ) { assert ( plot ); assert ( plotLast ); // If only one element... if ( plot->plotNext == plot ) { assert ( plotLast == plot ); plotLast = NULL; fprintf(stderr,"list::delete1 %x\n",plot); delete plot; } // If more than one element... else { if ( plotLast == plot->plotNext ) plotLast = plot; Listed(T)* plotTemp = plot->plotNext; *plot = *(plot->plotNext); fprintf(stderr,"list::delete2 %x\n",plotTemp); delete plotTemp; } } */ //////////////////////////////////////////////////////////////////////////////// template T& List::add ( ) { ListedObject* plot = new ListedObject ; ////fprintf(stderr,"list::add %x\n",plot); if ( NULL != plotLast ) { plot->plotNext = plotLast->plotNext ; plotLast->plotNext = plot ; plotLast = plot ; } else { plot->plotNext = plot ; plotLast = plot ; } return *plot ; } //////////////////////////////////////////////////////////////////////////////// template T& List::push ( ) { ListedObject* plot = new ListedObject ; ////fprintf(stderr,"list::push %x\n",plot); if ( NULL != plotLast ) { plot->plotNext = plotLast->plotNext ; plotLast->plotNext = plot ; } else { plot->plotNext = plot ; plotLast = plot ; } return *plot ; } //////////////////////////////////////////////////////////////////////////////// template void List::pop ( ) { ListedObject* plot = plotLast->plotNext ; if ( plot->plotNext == plot ) plotLast = NULL ; else plotLast->plotNext = plot->plotNext ; ////fprintf(stderr,"list::pop %x\n",plot); delete plot ; } //////////////////////////////////////////////////////////////////////////////// template int List::getCard ( ) const { Listed(T)* pt ; int i = 0 ; foreach ( pt, *this ) i++ ; return i ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::setFirst ( ) { return ( NULL != plotLast ) ? plotLast->plotNext : NULL ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::setNext ( ListedObject* plot ) { return ( NULL == plot && NULL != plotLast ) ? plotLast->plotNext : ( plot != plotLast ) ? plot->plotNext : NULL ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::getFirst ( ) const { return ( NULL != plotLast ) ? plotLast->plotNext : NULL ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::getSecond ( ) const { return getNext(getFirst()) ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::getLast ( ) const { return ( NULL != plotLast ) ? plotLast : NULL ; } //////////////////////////////////////////////////////////////////////////////// template ListedObject* List::getNext ( const ListedObject* plot ) const { return ( NULL == plot && NULL != plotLast ) ? plotLast->plotNext : ( plot != plotLast ) ? plot->plotNext : NULL ; } //////////////////////////////////////////////////////////////////////////////// template bool List::contains ( const T& t ) const { ListedObject* pt ; foreach ( pt, *this ) if ( t == *pt ) return true ; return false ; } //////////////////////////////////////////////////////////////////////////////// template bool List::isEmpty ( ) const { return ( NULL == plotLast ) ; } #endif //_NL_LIST_ /////////////////////////////////////////////////////////////