Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

474 lines
13 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
slist.hxx
LM 3.0 Generic slist package
This header file contains a generic list "macro" that can be used to
create an efficient singly linked list implementation for any type.
USAGE:
class DUMB
{
[...]
public:
int Compare( const DUMB * pd )
{ return (( _i == pd->_i ) ? 0 : (( _i < pd->_i ) ? -1 : 1 ) ); }
[...]
};
DECLARE_SLIST_OF(DUMB)
DEFINE_SLIST_OF(DUMB) // or DEFINE_EXT_SLIST_OF(DUMB)
SLIST_OF(DUMB) dumSlist;
ITER_SL_OF( DUMB ) iterDum( dumSlist );
main()
{
DUMB *pd;
pd = new DUMB( somedata );
dumSlist.Add( pd );
while ( ( pd = iterDum.Next() ) != NULL )
pd->DoSomething();
}
To use an SLIST in a class definition, then do something like:
----------- MyHeader.hxx ----------
//#include <slist.hxx>
DECLARE_SLIST_OF(DUMB)
class MYCLASS
{
private:
SLIST_OF( DUMB ) _slDumb;
...
};
----------- MyHeader.cxx ----------
//#include <slist.hxx>
//#include <MyHeader.hxx>
DEFINE_SLIST_OF(DUMB);
...
-----------------------------------
FILE HISTORY:
johnl 28-Jun-1990 Created
johnl 24-Jul-1990 Changed to use slist.cxx
johnl 11-Oct-1990 Only keeps pointers in Slist (doesn't copy)
johnl 30-Oct-1990 Made functional changes as per Peterwi's requests
(Iter doesn't advance, added some funct. to
internal nodes etc.)
johnl 7-Mar-1991 Code review changes
Johnl 9-Jul-1991 Broke SLIST into define and declare components
beng 26-Sep-1991 Removed LM_2 versions
KeithMo 23-Oct-1991 Added forward references.
*/
#ifndef _SLIST_HXX_
#define _SLIST_HXX_
// DebugPrint() declaration macro.
#if defined(DEBUG)
#define DBG_PRINT_SLIST_IMPLEMENTATION { _DebugPrint(); }
#else
#define DBG_PRINT_SLIST_IMPLEMENTATION { ; }
#endif
#define DECLARE_DBG_PRINT_SLIST \
void _DebugPrint () const ; \
void DebugPrint () const DBG_PRINT_SLIST_IMPLEMENTATION
//
// Forward references.
//
DLL_CLASS SL_NODE;
DLL_CLASS SLIST;
DLL_CLASS ITER_SL;
/*************************************************************************
NAME: SL_NODE
SYNOPSIS: Storage class for the SLIST type
INTERFACE: Set() - stores a pointer in the node
HISTORY:
beng 26-Sep-1991 Header added
**************************************************************************/
DLL_CLASS SL_NODE
{
friend class SLIST;
friend class ITER_SL;
public:
SL_NODE( SL_NODE *pslnode, VOID *pv )
: _pslnodeNext(pslnode), _pelem(pv) { }
VOID Set( SL_NODE *pslnode, VOID *pv )
{
/* Note: we guarantee the node is the last thing set
* (this allows us to do current->Set( current->Next, newelem)
* without trashing ourselves).
*/
_pelem = pv;
_pslnodeNext = pslnode;
}
SL_NODE *_pslnodeNext;
VOID * _pelem;
};
/*************************************************************************
NAME: ITER_SL
SYNOPSIS: Forward iterator for the SLIST class
The iterator "points" to the element that would be returned on the
next call to Next.
INTERFACE:
ITER_SL( ) - Constructor
~ITER_SL() - Destructor
Reset() - Reset the iterator to its initial state
operator()() - Synonym for next
Next() - Goto the next element in the list
QueryProp() - Returns the current property this iterator
is pointing to
USES: SLIST
HISTORY:
johnl 07-25-90 Created
johnl 10-11-90 Added QueryProp (request from Peterwi)
johnl 10-30-90 Removed Queryprop in favor of functional
change in iterator (item returned by next
is the current item).
**************************************************************************/
DLL_CLASS ITER_SL
{
friend class SLIST;
public:
ITER_SL( SLIST *psl );
ITER_SL( const ITER_SL& itersl );
~ITER_SL();
VOID Reset();
VOID* operator()() { return Next(); }
VOID* Next();
VOID* QueryProp();
private:
SL_NODE *_pslnodeCurrent; // Current item pointer
SLIST *_pslist; // Pointer to slist
BOOL _fUsed; // Flag to bump on first next call or not
ITER_SL *_psliterNext; // Pointer to next registered iterator
};
/*************************************************************************
NAME: SLIST
SYNOPSIS: Parameterized slist implementation
INTERFACE:
DECLARE_SLIST_OF() - Produces a declaration for an slist
of itemtype. Generally used in the header file.
DEFINE_SLIST_OF() - Produces type specific code. Should
be used once in a source file.
DEFINE_EXT_SLIST_OF() - Produces code for an slist of itemtype
with several additional methods
(IsMember, Remove(itemtype)), see below.
SLIST_OF() - Declares an slist of itemtype called
MySlist. If you do not want the
elements automatically deleted
in Clear or on destruction, then
pass FALSE to the constructor (the
fDestroy parameter defaults to TRUE.
ITER_SL_OF() - Declares an slist iterator
for iterating through the slist
Clear() - Specifically delete all elements in the slist.
IsMember() - Returns true if the element belongs to the
slist. NOTE: IS ONLY DEFINED FOR THE EXTENDED
SLIST (i.e., one that has been declared with
the DECLARE_EXT_SLIST_OF macro.
QueryNumElem() - Returns the number of elements
in the slist.
Add() - Adds the passed pointer to an object to the
slist (note, DO NOT ADD NULL POINTERS, Add WILL
Assert out if you do this).
Append() - Adds the passed pointer to the end of the
slist.
Insert() - Adds the passed pointer to the
"left" of the passed iterator.
Remove() - Finds element e and removes it from the list,
returning the item. Is only defined if the
DECLARE_EXT_SLIST_OF macro is used.
USES: ITER_SL
NOTES:
BumpIters() - For any iterators pointing to the passed
iter node, BumpIters calls iter.Next(). Used
when deleting an item from the list.
Register() - Registers an iterator with the slist
Deregister() - Deregisters an iterator with the slist
SetIters() - Sets all registered iters to the
passed value.
SetIters( CompVal, NewVal ) - Changes all registered iterators
that are pointing at SL_NODE CompVal to point to SL_NODE
NewVal (used when playing node games).
HISTORY:
Johnl 28-Jun-1990 Created
Johnl 12-Jul-1990 Made iters safe for deleting
Johnl 24-Jul-1990 Converted to use slist.cxx
KeithMo 09-Oct-1991 Win32 Conversion.
**************************************************************************/
DLL_CLASS SLIST
{
friend class ITER_SL;
public:
SLIST();
~SLIST();
// VOID Clear(); <<-- Defined in macro expansion
UINT QueryNumElem();
APIERR Add( VOID * pelem );
APIERR Append( VOID * pelem );
APIERR Insert( VOID * pelem, ITER_SL& sliter );
VOID* Remove( ITER_SL& sliter );
DECLARE_DBG_PRINT_SLIST
protected:
SL_NODE *_pslHead, *_pslTail;
ITER_SL *_psliterRegisteredIters; // Pointer to list of registered iters
protected:
VOID Register( ITER_SL * psliter );
VOID Deregister( ITER_SL * psliter );
VOID BumpIters( SL_NODE * pslnode );
VOID SetIters( SL_NODE * pslnode );
VOID SetIters( SL_NODE * CompVal, SL_NODE *NewVal );
BOOL CheckIter( ITER_SL * psliter );
SL_NODE* FindPrev( SL_NODE * pslnode );
};
/*************************************************************************
NAME: DECLARE_SLIST_OF
SYNOPSIS: Macro which expands into the type-specific portions of
the SLIST package.
NOTES:
The user can also use:
SLIST_OF( type ) - for declaring SLIST lists
ITER_SL_OF(type) - for declaring Forward iterators
See the beginning of this file for usage of this package.
HISTORY:
johnl 24-Jul-90 Created
beng 30-Apr-1991 New syntax for constructor inheritance
**************************************************************************/
#define SLIST_OF(type) SLIST_OF_##type
#define ITER_SL_OF(type) ITER_SL_##type
/*------ SLIST Macro expansion -------*/
#define DECL_SLIST_OF(type,dec) \
class dec SLIST_OF(type); \
\
class dec ITER_SL_OF(type) : public ITER_SL \
{ \
public: \
ITER_SL_OF(type)( SLIST& sl ) : ITER_SL(&sl) {; } \
ITER_SL_OF(type)( const ITER_SL_OF(type)& pitersl ) : \
ITER_SL(pitersl) {; } \
\
type* Next() \
{ return (type *)ITER_SL::Next(); } \
\
type* operator()(VOID) \
{ return Next(); } \
\
type* QueryProp() \
{ return (type *)ITER_SL::QueryProp(); } \
}; \
\
class dec SLIST_OF(type) : public SLIST \
{ \
private: \
BOOL _fDestroy; \
\
public: \
SLIST_OF(type) ( BOOL fDestroy = TRUE ) : \
SLIST( ), \
_fDestroy(fDestroy) {; } \
\
~SLIST_OF(type)() { Clear(); } \
\
VOID Clear(); \
\
APIERR Add( const type * pelemNew ) \
{ \
return SLIST::Add( (VOID *)pelemNew ); \
} \
\
APIERR Append( const type * pelemNew ) \
{ \
return SLIST::Append( (VOID *)pelemNew ) ; \
} \
\
APIERR Insert( const type *pelemNew, ITER_SL_OF(type)& sliter ) \
{ \
return SLIST::Insert( (VOID *)pelemNew, sliter ); \
} \
\
type* Remove( ITER_SL_OF(type)& sliter ) \
{ \
return (type *) SLIST::Remove( sliter ); \
} \
\
/* You can only use these */ \
/* if you use DEFINE_EXT_SLIST_OF; otherwise */ \
/* you will get unresolved externals. */ \
type* Remove( type& e ); \
BOOL IsMember( const type& e ); \
};
#define DEFINE_SLIST_OF(type) \
VOID SLIST_OF(type)::Clear() \
{ \
register SL_NODE *_pslnode = _pslHead, *_pslnodeOld = NULL; \
\
while ( _pslnode != NULL ) \
{ \
_pslnodeOld = _pslnode; \
_pslnode = _pslnode->_pslnodeNext; \
if ( _fDestroy ) \
delete ((type *)_pslnodeOld->_pelem ) ; \
delete _pslnodeOld; \
} \
_pslHead = _pslTail = NULL; \
\
SetIters( NULL ); \
}
#define DEFINE_EXT_SLIST_OF(type) \
DEFINE_SLIST_OF(type) \
\
/* Remove is here so it can see the Compare method of the element */ \
type* SLIST_OF(type)::Remove( type& e ) \
{ \
register SL_NODE *_pslnode = _pslHead, *_pslnodePrev = NULL; \
\
while ( _pslnode != NULL ) \
{ \
if ( !((type *)_pslnode->_pelem)->Compare( &e ) ) \
{ \
if ( _pslnodePrev != NULL ) /* if not first node in list */ \
{ \
_pslnodePrev->_pslnodeNext = _pslnode->_pslnodeNext; \
\
/* patch up tail pointer if last item in list */ \
if ( _pslTail == _pslnode ) \
_pslTail = _pslnodePrev; \
} \
else \
if ( _pslnode->_pslnodeNext == NULL ) \
_pslHead = _pslTail = NULL; /* only item in list */ \
else \
_pslHead = _pslnode->_pslnodeNext; \
\
BumpIters( _pslnode ); /* Move iters to next node... */ \
\
type* _pelem = (type *)_pslnode->_pelem; \
delete _pslnode; \
return _pelem; \
} \
else \
{ \
_pslnodePrev = _pslnode; \
_pslnode = _pslnode->_pslnodeNext; \
} \
} \
\
return NULL; \
} \
\
BOOL SLIST_OF(type)::IsMember( const type& e ) \
{ \
register SL_NODE *_pslnode = _pslHead; \
\
while ( _pslnode != NULL ) \
{ \
if ( !((type *)_pslnode->_pelem)->Compare( &e ) ) \
return TRUE; \
else \
_pslnode = _pslnode->_pslnodeNext; \
} \
\
return FALSE; \
}
// Helper macros for code preservation
#define DECLARE_SLIST_OF(type) \
DECL_SLIST_OF(type,DLL_TEMPLATE)
#endif // _SLIST_HXX_