mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. 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;
}