/* ....[@@@..[@@@..............[@.................. MUD++ is a written from ....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and ....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++. ....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing ....[@......[@..[@@@@@..[@@@@@.................. development project. All ................................................ contributions are welcome. ....Copyright(C).1995.Melvin.Smith.............. Enjoy. ------------------------------------------------------------------------------ Melvin Smith (aka Fusion) msmith@hom.net MUD++ development mailing list mudpp@van.ml.org ------------------------------------------------------------------------------ llist.cc */ // TEMPLATE FILE int Node::allocated_nodes = 0; #ifdef _ARRAY_H Array< Node *> free_nodes( 128,128 ); void * Node::operator new( size_t size ) { if ( !free_nodes.length() ) { int i; Node * newtable = (Node *) new char[size<<7]; allocated_nodes += 128; for ( i=0; i < 128; i++) { free_nodes.add( newtable + i); } } return free_nodes.removeTop(); } void Node::operator delete( void * ptr ) { free_nodes.add( (Node *) ptr ); } int Node::getFreeCount() { return free_nodes.length(); } #else int Node::getFreeCount() { return -1; } #endif // _ARRAY_H template < class T > void LList< T >::copy( const LList< T > & x ) { Node * node = x.head; if( &x != this ) { destroyList(); while( node ) { add( (T*)node->obj ); node = node->next; } } } template < class T > void LList< T >::destroyList() { // Make sure its not a copied list that was used for iterating // which is just going out of scope. if( !( flags & RDONLY ) ) { if( head ) { for( current = head; head; head = current ) { current = current->next; delete head; } } } else { flags &= ~RDONLY; // clear read only bit head = current = 0; } } template < class T > void LList< T >::addTop( T * obj ) { if( !obj ) return; else if( flags & RDONLY ) return; // need to bug this later Node * newNode = new Node( (void*)obj ); newNode->next = head; head = newNode; if( ! current ) current = newNode; } template < class T > void LList< T >::add( T * obj ) { if( !obj ) return; else if( flags & RDONLY ) return; // need to bug this later Node * newNode = new Node( (void*)obj ); if( !head ) { head = current = newNode; return; } newNode->next = current; if( head == current ) { head = newNode; current = newNode; return; } Node * tlast; for( tlast = head; tlast->next; tlast = tlast->next ) { if( tlast->next == current ) { tlast->next = newNode; break; } } if( !tlast->next ) tlast->next = newNode; current = newNode; } // Add a node after current node, used for sequential building // of a list mostly. template < class T > void LList< T >::addAfterCurrent( T * obj ) { if( !obj ) return; else if( flags & RDONLY ) return; // need to bug this later Node * newNode = new Node( (void*)obj ); if( !head ) { head = current = newNode; return; } else if( !current ) current = head; newNode->next = current->next; current->next = newNode; } template < class T > T* LList< T >::remove( T * obj ) { if( !head ) return NULL; else if( flags & RDONLY ) return NULL; // need to bug this later Node * rem; Node * tlast = 0; T * delobj; if( head->obj == (void*)obj ) { if( current == head ) current = head->next; rem = head; head = head->next; delobj = (T*)rem->obj; delete rem; return delobj; } for( rem = head; rem; rem = rem->next ) { if( rem->obj == (void*)obj ) { if( rem == current ) current = current->next; if( tlast ) tlast->next = rem->next; delobj = (T*)rem->obj; delete rem; return delobj; } tlast = rem; } return NULL; } template < class T > T *LList< T >::remove() { if( !head ) return 0; else if( flags & RDONLY ) return 0; // need to bug this later Node * rem = current; if( !rem ) return 0; else if( rem == head ) { head = head->next; current = current->next; } else { for( current = head; current->next; current = current->next ) { if( current->next == rem ) { current->next = rem->next; break; } } } T * obj = (T*)rem->obj; delete rem; return obj; } // Does node by node copy. This is so constructed objects // that have list data will copy correctly. Note that the // actual object pointers still point to same address. template < class T > LList< T >::LList( const LList< T > & x ) : head(0), current(0), flags(0) { Node * node = x.head; while( node ) { add( (T*)node->obj ); node = node->next; } } template < class T > void LList< T >::next() const { if( current ) { //const_cast< LList< T > * >(this)->current = current->next; ((LList< T > *)this)->current = current->next; } } // Do read-only copy of a list. Items can't be added or removed // from this list. It is only for iterating, etc. and is written // specifically for this with the least overhead. template < class T > const LList< T > & LList< T >::operator = ( const LList< T > & x ) { if( &x != this ) { destroyList(); head = x.head; current = x.head; flags |= RDONLY; } return *this; } template < class T > T *LList< T >::peek() const { if( !current ) return 0; return (T*)current->obj; } template < class T > T *LList< T >::peekNext() const { if( !current || !current->next ) return 0; return (T*)current->next->obj; }