//**************************************
//
//INCLUDE files for :David Nugent's link
// ed list container classes
//**************************************
//
// +++Date last modified: 05-Jul-1997
////////////////////////////////////////
////////////////////////
// MODULE
// list.hpp
// CREATED
// davidn 03 Dec 1994 23:34
// David L. Nugent
// This class implementation is donated
// to the public domain
// DESCRIPTION
// Classes supporting linked list contai
// ners
// CLASSES/TYPES
// class node
//Represents a single link in a doubly l
// inked list
// class list
//Base class which handles all of the li
// nked list management
// class iter
//Base class for handling iteration thro
// ugh a linked list
// class Node
//Template class used for containment of
// an arbitrary type T
// class List
//Linked list class which is used to get
// /store/remove nodes
//from a linked list containing data
// class Iter
//Used for iteration of a List
// SYNOPSIS
// These classes allow any arbitrary typ
// e to be contained in a
// type-safe linked list. All of the com
// mon code for list
// management itself is contained in a c
// ommon set of classes:
// node, list and iter. Template classes
// derived from these
// allow inline access to the underlying
// base classes via a
// type-safe front-end.
////////////////////////////////////////
////////////////////////
#if !defined( _list_h )
#define _list_h
class list;
// Generic 'node' class
class node
{
friend class iter;
public:
node( list * L =0, node * prv =0, node * nxt =0 )
: mylist( 0 ), Prev( 0 ), Next( 0 )
{ link( L, prv, nxt ); }
virtual ~node( void )
{ unlink( ); }
void link( list * L, node * prv, node * nxt );
void unlink( );
node * prevNode( void ) const
{ return Prev; }
node * nextNode( void ) const
{ return Next; }
private:
list * mylist;
node * Prev, * Next;
};
// template node frontend
template
class Node : public node
{
public:
Node( T data, list * L =0, node * prv =0, node * nxt =0 )
: node( L, prv, nxt ), Data( data ) {}
Node
{ return (Node
Node
{ return (Node
T & ref2data( void ) const
{ return ( T & )Data; }
T * ptr2data( void ) const
{ return ( T * )&Data; }
T data( void ) const
{ return Data; }
private:
T Data;
};
// Generic 'list' class
class list
{
friend class node;
public:
list( void )
: First( 0 ), Last( 0 ), nodes( 0 ) {}
virtual ~list( void )
{ purge(); }
void purge( void );
long items( void ) const
{ return nodes; }
void addatstart( node * n )
{ n->link( this, 0, First ); }
void addatend( node * n )
{ n->link( this, Last, 0 ); }
void addafter( node * n, node * prv )
{ n->link( this, prv, 0 ); }
void addbefore( node * n, node * nxt )
{ n->link( this, 0, nxt ); }
node * firstNode( void ) const
{ return First; }
node * lastNode( void ) const
{ return Last; }
protected:
node * First, * Last;
long nodes;
};
// Container class List
template
class List : public list
{
public:
List( void ) : list() {}
Node
{ return new Node
Node
{ return (Node
Node
{ return (Node
};
enum trOp
{
FIRST, LAST, PREV, NEXT, CURR
};
#define TR_OK 0
#define TR_EMPTY -2
#define TR_NOMORE -3
class iter
{
public:
iter( list & L )
: mylist( L ), nptr( 0 ) {}
iter( iter const & I )
: mylist( I.mylist ), nptr( I.nptr ) {}
iter & operator=( iter const & I )
{ if ( &I.mylist == &mylist ) nptr = I.nptr; return *this; }
void reset( void )
{ nptr = 0; }
int traverse( trOp op );
int current( void )
{ return traverse( CURR ); }
int first( void )
{ return traverse( FIRST ); }
int last ( void )
{ return traverse( LAST ); }
int prev( void )
{ return traverse( PREV ); }
int next( void )
{ return traverse( NEXT ); }
protected:
list & mylist;
node * nptr;
};
// Iterator
template
class Iter : public iter
{
public:
typedef int (*comparator)( const &T, const T&);
Iter( List
: iter( L ) {}
Iter( Iter
: iter( I ) {}
Iter
{ iter::operator=( I ); return *this; }
List
{ return ( List
Node
{ return ( Node
T & ref2data( void ) const
{ return atNode()->ref2data(); }
T * ptr2data( void ) const
{ return atNode()->ptr2data(); }
T data( void ) const
{ return atNode()->data(); }
void addFirst( T data )
{ myList().addatstart( new Node
void addLast( T data )
{ myList().addatend( new Node
void addAfter( T data )
{ myList().addafter( new Node
void addBefore( T data )
{ myList().addbefore( new Node
void add( T data, trOp op );
trOp locate( T & data, comparator compare );
int addsorted( T data, comparator compare, int adddupe =0 );
};
template
{
switch( op )
{
case FIRST:addFirst( data );break;
case LAST:addLast( data ); break;
case PREV:addBefore( data );break;
case CURR: case NEXT: addAfter( data );break;
}
}
template
trOp
Iter
{
register trOp rc;
register Node
if ( n == 0 )// Add to start of empty list
rc = FIRST;
else
{
rc = LAST;
while ( rc == LAST && n != 0 )
{
int r = compare( data, n->ref2data() );
if ( r == 0 )// Found an exact match
rc = CURR;
else if ( r < 0 )// We've gone past it
rc = PREV;
else
n = n->next();
}
}
nptr = n;
return rc;
}
template
int
Iter
{
trOp r;
if ((( r = locate( data, compare )) != CURR ) || adddupe )
{
add( data, r );
return 1;
}
return 0;
}
#endif// _list_h
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
Terms of Agreement:
By using this code, you agree to the following terms...
1) You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for langauges that allow it) freely and with no charge.
2) You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this code from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
//**************************************
//
// Name: David Nugent's linked list cont
// ainer classes
// Description:Implementation of class n
// ode, list & iterator
// By: Bob Stout (republished under Open
// Content License)
//
//This code is copyrighted and has// limited warranties.Please see http://
// www.1CPlusPlusStreet.com/xq/ASP/txtCodeI
// d.707/lngWId.3/qx/vb/scripts/ShowCode.ht
// m//for details.//**************************************
//
// +++Date last modified: 05-Jul-1997
////////////////////////////////////////
/////////////////////
// MODULE
// list.cpp
// CREATED
// davidn 03 Dec 1994 23:59
// David L. Nugent
// This class implementation is donated
// to the public domain
// DESCRIPTION
// Implementation of class node, list &
// iter
// FUNCTIONS
// node::unlink()
//Destroys linkage from a list and remov
// es it from a
//linked list
// node::link()
//Links a node into a linked list
// list::purge()
//Removes all linked list entries
// iter::traverse()
//Provides full traversal functions for
// nodes in a
//linked list
////////////////////////////////////////
/////////////////////
// Implementation of class list & friend
// s
#include "list.hpp"
void
node::unlink()
{
if ( mylist )
{
// Unlink from previous
if ( Prev )
Prev->Next = Next;
else
mylist->First = Next;
// Unlink from next
if ( Next )
Next->Prev = Prev;
else
mylist->Last = Prev;
mylist->nodes--;
mylist = 0;
Prev = Next = 0;
}
}
void
node::link( list * L, node * prv, node * nxt )
{
// If currently linked, then unlink it
if ( mylist )
unlink();
// Link it to the list
if ( L )
{
mylist = L;
// Add after previous
if ( prv )
{
Prev = prv;
Next = prv->Next;
}
// Add before next
else if ( nxt )
{
Next = nxt;
Prev = nxt->Prev;
}
// Else just add to end
else
{
Next = 0;
Prev = L->Last;
}
if ( Prev )
Prev->Next = this;
else
L->First = this;
if ( Next )
Next->Prev = this;
else
L->Last = this;
mylist->nodes++;
}
}
void
list::purge( void )
{
while ( First )
delete First;
}
int
iter::traverse( trOp op )
{
if ( mylist.firstNode() == 0 )
return TR_EMPTY;
switch ( op )
{
case NEXT:
if ( nptr )
{
nptr = nptr->Next;
break;
}
case FIRST:
nptr = mylist.firstNode();
break;
case PREV:
if ( nptr )
{
nptr = nptr->Prev;
break;
}
case LAST:
nptr = mylist.lastNode();
break;
case CURR:
break;
}
return ( nptr ) ? TR_OK : TR_NOMORE;
}