windows-nt/Source/XPSP1/NT/admin/netui/common/h/tree.hxx
2020-09-26 16:20:57 +08:00

337 lines
12 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
TREE.hxx
LM 3.0 Generic general tree package
This header file contains a generic TREE macro that can be used to
create an efficient general tree implementation for any type.
USAGE:
#include <tree.hxx>
DECLARE_TREE_OF(TEST)
void main( void )
{
TEST * pTest = new TEST ;
pTest->Set(20) ;
TREE_OF_TEST treeTest( pTest ) ;
for ( int i = 0 ; i < 10 ; i++ )
{
TREE_OF_TEST *ptreeTest = new TREE_OF_TEST( new TEST( i ) ) ;
if ( ptreeTest != NULL )
if ( ptreeTest->QueryProp() != NULL )
treeTest.JoinSubtreeLeft( ptreeTest ) ;
else
delete ptreeTest ;
}
TREE_OF_TEST *pt = &treeTest ;
pt->QueryProp()->Print() ;
while ( (pt = pt->QueryLeft()) != NULL )
pt->QueryProp()->Print() ;
treeTest->Clear() ; // Delete properties & nodes
}
FILE HISTORY:
johnl 06-Sep-1990 Created
beng 08-Mar-1991 Obnoxious WS delta for prettier UI.HLP
beng 26-Sep-1991 C7 delta
*/
#ifndef _TREE_HXX_
#define _TREE_HXX_
// DebugPrint() declaration macro.
#if defined(DEBUG)
#define DBG_PRINT_TREE_IMPLEMENTATION { _DebugPrint(); }
#else
#define DBG_PRINT_TREE_IMPLEMENTATION { ; }
#endif
#define DECLARE_DBG_PRINT_TREE \
void _DebugPrint () const ; \
void DebugPrint () const DBG_PRINT_TREE_IMPLEMENTATION
/*************************************************************************
NAME: TREE
SYNOPSIS: Parameterized General Tree implementation
INTERFACE:
DECLARE_TREE_OF(itemtype) - Produces a declaration for
a TREE of itemtype.
TREE() - Constructor; initializes pointers
~TREE() - Destructor; unlinks this subtree from the tree
QueryNumElem() - Returns the number of tree nodes in the
subtree (counting "this" node).
QueryParent() - Returns the parent of this node
QueryLeft() - Returns the left sibling of this node (NULL if
there isn't one).
QueryRight() - Same as QueryLeft except returns the right
sibling.
QueryFirstSubtree() - Returns the left most child of
this node.
QueryRightSubtree() - Returns the right most child
of this node.
JoinSubtreeLeft() - Joins passed tree as the left most
child of this node.
JoinSubtreeRight() - Joins passed tree as the right most
child of this node.
JoinSiblingLeft() - Joins the passed tree immediately to
the left of this node as a sibling.
JoinSiblingRight() - Joins the passed tree immediately to
the right of this node as a sibling.
BreakOut() - Breaks this subtree out from the tree and
returns this subtree.
QueryProp() - Returns a pointer to the object this node
contains.
SetProp() - Sets the pointer at this tree node.
Clear() - Removes subtree & specifically calls delete on each
property in the subtree. While the node Clear is called
on is not deleted, the property is (its pointer being
set to NULL after being deleted). (NOTE: Clear is only
defined in the macro expansion; it is included here for
completeness.)
CAVEATS:
Currently, the destructor doesn't delete the property.
However, Clear does specifically delete each property, in
addition to deleting each node (the node which Clear was
called from isn't deleted, though its property is).
HISTORY:
Johnl 6-Sep-1990 Created
Johnl 16-Sep-1990 Moved property from macro expanded
class to main TREE class (benefits
iterator effeceincy).
johnl 19-Sep-1990 Added JoinSibling{Left|Right}
beng 26-Sep-1991 Modified constructor for C7
KeithMo 09-Oct-1991 Win32 Conversion.
**************************************************************************/
DLL_CLASS TREE
{
public:
TREE( VOID * pelem );
~TREE();
UINT QueryNumElem() const;
TREE* QueryParent() const
{ return _ptParent; }
TREE * QueryLeft() const
{ return _ptLeft; }
TREE * QueryRight() const
{ return _ptRight; }
TREE * QueryFirstSubtree() const
{ return _ptLeftChild; }
TREE * QueryLastSubtree() const;
VOID JoinSubtreeLeft( TREE * ptree );
VOID JoinSubtreeRight( TREE * ptree );
VOID JoinSiblingLeft( TREE * ptree );
VOID JoinSiblingRight( TREE * ptree );
TREE * BreakOut();
VOID SetProp( VOID * const vp )
{ _pvData = vp; }
VOID* QueryProp() const
{ return _pvData; }
DECLARE_DBG_PRINT_TREE
protected:
// Helper routine that unlinks this subtree from the tree
// (each node is unlinked on destruction).
//
VOID Unlink();
private:
// Links
//
TREE *_ptLeft, // left sibling pointer
*_ptRight, // right sibling
*_ptParent, // parent
*_ptLeftChild; // child pointer
VOID *_pvData; // property of this node (can't be NULL)
// Helper routines to set the pointers
//
VOID SetLeft( TREE * pt )
{ _ptLeft = pt; }
VOID SetRight( TREE * pt )
{ _ptRight = pt; }
VOID SetFirstSubtree( TREE * pt )
{ _ptLeftChild = pt; }
VOID SetParent( TREE * pt )
{ _ptParent = pt; }
UINT _QueryNumElemAux() const;
};
/**************************************************************************
NAME: DECLARE_TREE_OF( type )
SYNOPSIS: Macro that expands into the type specific portions of the
TREE package.
NOTES:
The user can also use:
TREE_OF( type ) - for declaring TREE lists
See the beginning of this file for usage of this package.
The QueryProp, SetProp & Clear are only defined in this
macro expansion (and thus only for TREE_OF_* types).
_pProperty - Pointer to this tree nodes property
(can be NULL).
_fDelProp - Flag telling the destructor to delete properties
on node destruction (currently used by Clear for
effeciency's sake; may want to export as a Set
option).
CAVEATS:
The TREE interface must not cross the app-dll boundary.
HISTORY:
johnl 6-Sep-90 Created
johnl 19-Sep-90 Added JoinSibling{Left|Right}
**************************************************************************/
#define TREE_OF(type) TREE_OF_##type
#define DECL_TREE_OF(type,dec) \
\
class dec TREE_OF(type) : public TREE \
{ \
private: \
static BOOL _fDelProp; \
\
public: \
TREE_OF(type) ( type * const pelem ) : ( (VOID *) pelem ) \
{ _fDelProp = FALSE; } \
\
~TREE_OF(type)() \
{ \
if ( _fDelProp ) \
{ \
type * _prop = (type *) TREE::QueryProp(); \
delete _prop; \
} \
\
/* pttmp is used because pt's right pointer is set to
* NULL on the delete, so we cache it in pttmp
*/ \
TREE_OF(type) *pt = QueryFirstSubtree(), *pttmp; \
while ( pt != NULL ) \
{ \
pttmp = pt->QueryRight(); \
delete pt; \
pt = pttmp; \
} \
\
} \
\
VOID Clear() \
{ \
_fDelProp = TRUE; \
delete this; \
_fDelProp = FALSE; \
} \
\
type * QueryProp() const \
{ return (type *)TREE::QueryProp(); } \
\
VOID SetProp( type * pelem ) \
{ TREE::SetProp( (VOID *) pelem ); } \
\
TREE_OF(type)* QueryParent() const \
{ return (TREE_OF(type) *) TREE::QueryParent(); } \
\
TREE_OF(type)* QueryLeft() const \
{ return (TREE_OF(type) *) TREE::QueryLeft(); } \
\
TREE_OF(type) * QueryRight() const \
{ return (TREE_OF(type) *) TREE::QueryRight(); } \
\
TREE_OF(type) * QueryFirstSubtree() const \
{ return (TREE_OF(type) *) TREE::QueryFirstSubtree(); } \
\
TREE_OF(type) * QueryLastSubtree() const \
{ return (TREE_OF(type) *) TREE::QueryLastSubtree(); } \
\
VOID JoinSubtreeLeft( TREE * ptree ) \
{ TREE::JoinSubtreeLeft( (TREE *) ptree ); } \
\
VOID JoinSubtreeRight( TREE * ptree ) \
{ TREE::JoinSubtreeRight( (TREE *) ptree ); } \
\
VOID JoinSiblingLeft( TREE * ptree ) \
{ TREE::JoinSiblingLeft( (TREE *) ptree ); } \
\
VOID JoinSiblingRight( TREE * ptree ) \
{ TREE::JoinSiblingRight( (TREE *) ptree ); } \
\
TREE_OF(type)* BreakOut() \
{ return (TREE_OF(type) *) TREE::BreakOut(); } \
};
#define DECLARE_TREE_OF(type) \
DECL_TREE_OF(type,DLL_TEMPLATE)
#endif // _TREE_HXX_