windows-nt/Source/XPSP1/NT/enduser/troubleshoot/bn/glnkenum.h
2020-09-26 16:20:57 +08:00

102 lines
2.4 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1997
//
// File: glnkenum.h
//
//--------------------------------------------------------------------------
//
// GLNKENUM.H
//
#if !defined(_GLNKENUM_H_)
#define _GLNKENUM_H_
// Base class for generic linkable object enumerators
class GLNKENUM_BASE
{
public:
// Construct an enumerator.
GLNKENUM_BASE ( const GLNKEL & lnkel, int iDir = 1 )
{
Reset( lnkel, iDir ) ;
}
// Position to the next pointer
GLNKEL * PlnkelNext () ;
// Return the current object pointer
inline GLNKEL * PlnkelCurrent()
{ return _plnkelNext ; }
// Set the enumerator to have a new base
void Reset ( const GLNKEL & lnkel, int iDir = 0 )
{
_plnkelStart = const_cast<GLNKEL *>(& lnkel) ;
_plnkelNext = NULL ;
if ( iDir >= 0 )
_iDir = iDir ;
}
protected:
GLNKEL * _plnkelStart ;
GLNKEL * _plnkelNext ;
int _iDir ; // Enumeration direction
};
#define BOOL_CROSS_PRODUCT(a,b) (((a) > 0) + (((b) > 0) * 2))
inline
GLNKEL * GLNKENUM_BASE :: PlnkelNext ()
{
GLNKEL * plnkelResult = NULL ;
switch ( BOOL_CROSS_PRODUCT( _plnkelNext != NULL, _iDir ) )
{
case BOOL_CROSS_PRODUCT( true, true ):
if ( _plnkelNext->PlnkelNext() != _plnkelStart )
plnkelResult =_plnkelNext = _plnkelNext->PlnkelNext() ;
break ;
case BOOL_CROSS_PRODUCT( true, false ):
if ( _plnkelNext != _plnkelStart )
plnkelResult = _plnkelNext = _plnkelNext->PlnkelPrev() ;
break ;
case BOOL_CROSS_PRODUCT( false, true ):
plnkelResult = _plnkelNext = _plnkelStart ;
break ;
case BOOL_CROSS_PRODUCT( false, false ):
plnkelResult = _plnkelNext = _plnkelStart->PlnkelPrev() ;
break ;
}
return plnkelResult ;
}
template <class L, bool bAnchor>
class GLNKENUM : public GLNKENUM_BASE
{
public:
// Construct an enumerator. If 'bAnchor', then the anchor object is
// skipped during enumeration.
GLNKENUM ( const L & lnkel, bool bIsAnchor = bAnchor, int iDir = 1 )
: GLNKENUM_BASE( lnkel, iDir )
{
if ( bIsAnchor )
PlnkelNext() ;
}
// Position to the next pointer
L * PlnkelNext ()
{ return (L *) GLNKENUM_BASE::PlnkelNext() ; }
// Return the current object pointer
L * PlnkelCurrent()
{ return (L *) _plnkelNext ; }
// Set the enumerator to have a new base
void Reset ( const L & lnkel, int iDir = -1 )
{ GLNKENUM_BASE::Reset( lnkel, iDir ) ; }
};
#endif