Source code of Windows XP (NT5)
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.

336 lines
12 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. TREE.hxx
  7. LM 3.0 Generic general tree package
  8. This header file contains a generic TREE macro that can be used to
  9. create an efficient general tree implementation for any type.
  10. USAGE:
  11. #include <tree.hxx>
  12. DECLARE_TREE_OF(TEST)
  13. void main( void )
  14. {
  15. TEST * pTest = new TEST ;
  16. pTest->Set(20) ;
  17. TREE_OF_TEST treeTest( pTest ) ;
  18. for ( int i = 0 ; i < 10 ; i++ )
  19. {
  20. TREE_OF_TEST *ptreeTest = new TREE_OF_TEST( new TEST( i ) ) ;
  21. if ( ptreeTest != NULL )
  22. if ( ptreeTest->QueryProp() != NULL )
  23. treeTest.JoinSubtreeLeft( ptreeTest ) ;
  24. else
  25. delete ptreeTest ;
  26. }
  27. TREE_OF_TEST *pt = &treeTest ;
  28. pt->QueryProp()->Print() ;
  29. while ( (pt = pt->QueryLeft()) != NULL )
  30. pt->QueryProp()->Print() ;
  31. treeTest->Clear() ; // Delete properties & nodes
  32. }
  33. FILE HISTORY:
  34. johnl 06-Sep-1990 Created
  35. beng 08-Mar-1991 Obnoxious WS delta for prettier UI.HLP
  36. beng 26-Sep-1991 C7 delta
  37. */
  38. #ifndef _TREE_HXX_
  39. #define _TREE_HXX_
  40. // DebugPrint() declaration macro.
  41. #if defined(DEBUG)
  42. #define DBG_PRINT_TREE_IMPLEMENTATION { _DebugPrint(); }
  43. #else
  44. #define DBG_PRINT_TREE_IMPLEMENTATION { ; }
  45. #endif
  46. #define DECLARE_DBG_PRINT_TREE \
  47. void _DebugPrint () const ; \
  48. void DebugPrint () const DBG_PRINT_TREE_IMPLEMENTATION
  49. /*************************************************************************
  50. NAME: TREE
  51. SYNOPSIS: Parameterized General Tree implementation
  52. INTERFACE:
  53. DECLARE_TREE_OF(itemtype) - Produces a declaration for
  54. a TREE of itemtype.
  55. TREE() - Constructor; initializes pointers
  56. ~TREE() - Destructor; unlinks this subtree from the tree
  57. QueryNumElem() - Returns the number of tree nodes in the
  58. subtree (counting "this" node).
  59. QueryParent() - Returns the parent of this node
  60. QueryLeft() - Returns the left sibling of this node (NULL if
  61. there isn't one).
  62. QueryRight() - Same as QueryLeft except returns the right
  63. sibling.
  64. QueryFirstSubtree() - Returns the left most child of
  65. this node.
  66. QueryRightSubtree() - Returns the right most child
  67. of this node.
  68. JoinSubtreeLeft() - Joins passed tree as the left most
  69. child of this node.
  70. JoinSubtreeRight() - Joins passed tree as the right most
  71. child of this node.
  72. JoinSiblingLeft() - Joins the passed tree immediately to
  73. the left of this node as a sibling.
  74. JoinSiblingRight() - Joins the passed tree immediately to
  75. the right of this node as a sibling.
  76. BreakOut() - Breaks this subtree out from the tree and
  77. returns this subtree.
  78. QueryProp() - Returns a pointer to the object this node
  79. contains.
  80. SetProp() - Sets the pointer at this tree node.
  81. Clear() - Removes subtree & specifically calls delete on each
  82. property in the subtree. While the node Clear is called
  83. on is not deleted, the property is (its pointer being
  84. set to NULL after being deleted). (NOTE: Clear is only
  85. defined in the macro expansion; it is included here for
  86. completeness.)
  87. CAVEATS:
  88. Currently, the destructor doesn't delete the property.
  89. However, Clear does specifically delete each property, in
  90. addition to deleting each node (the node which Clear was
  91. called from isn't deleted, though its property is).
  92. HISTORY:
  93. Johnl 6-Sep-1990 Created
  94. Johnl 16-Sep-1990 Moved property from macro expanded
  95. class to main TREE class (benefits
  96. iterator effeceincy).
  97. johnl 19-Sep-1990 Added JoinSibling{Left|Right}
  98. beng 26-Sep-1991 Modified constructor for C7
  99. KeithMo 09-Oct-1991 Win32 Conversion.
  100. **************************************************************************/
  101. DLL_CLASS TREE
  102. {
  103. public:
  104. TREE( VOID * pelem );
  105. ~TREE();
  106. UINT QueryNumElem() const;
  107. TREE* QueryParent() const
  108. { return _ptParent; }
  109. TREE * QueryLeft() const
  110. { return _ptLeft; }
  111. TREE * QueryRight() const
  112. { return _ptRight; }
  113. TREE * QueryFirstSubtree() const
  114. { return _ptLeftChild; }
  115. TREE * QueryLastSubtree() const;
  116. VOID JoinSubtreeLeft( TREE * ptree );
  117. VOID JoinSubtreeRight( TREE * ptree );
  118. VOID JoinSiblingLeft( TREE * ptree );
  119. VOID JoinSiblingRight( TREE * ptree );
  120. TREE * BreakOut();
  121. VOID SetProp( VOID * const vp )
  122. { _pvData = vp; }
  123. VOID* QueryProp() const
  124. { return _pvData; }
  125. DECLARE_DBG_PRINT_TREE
  126. protected:
  127. // Helper routine that unlinks this subtree from the tree
  128. // (each node is unlinked on destruction).
  129. //
  130. VOID Unlink();
  131. private:
  132. // Links
  133. //
  134. TREE *_ptLeft, // left sibling pointer
  135. *_ptRight, // right sibling
  136. *_ptParent, // parent
  137. *_ptLeftChild; // child pointer
  138. VOID *_pvData; // property of this node (can't be NULL)
  139. // Helper routines to set the pointers
  140. //
  141. VOID SetLeft( TREE * pt )
  142. { _ptLeft = pt; }
  143. VOID SetRight( TREE * pt )
  144. { _ptRight = pt; }
  145. VOID SetFirstSubtree( TREE * pt )
  146. { _ptLeftChild = pt; }
  147. VOID SetParent( TREE * pt )
  148. { _ptParent = pt; }
  149. UINT _QueryNumElemAux() const;
  150. };
  151. /**************************************************************************
  152. NAME: DECLARE_TREE_OF( type )
  153. SYNOPSIS: Macro that expands into the type specific portions of the
  154. TREE package.
  155. NOTES:
  156. The user can also use:
  157. TREE_OF( type ) - for declaring TREE lists
  158. See the beginning of this file for usage of this package.
  159. The QueryProp, SetProp & Clear are only defined in this
  160. macro expansion (and thus only for TREE_OF_* types).
  161. _pProperty - Pointer to this tree nodes property
  162. (can be NULL).
  163. _fDelProp - Flag telling the destructor to delete properties
  164. on node destruction (currently used by Clear for
  165. effeciency's sake; may want to export as a Set
  166. option).
  167. CAVEATS:
  168. The TREE interface must not cross the app-dll boundary.
  169. HISTORY:
  170. johnl 6-Sep-90 Created
  171. johnl 19-Sep-90 Added JoinSibling{Left|Right}
  172. **************************************************************************/
  173. #define TREE_OF(type) TREE_OF_##type
  174. #define DECL_TREE_OF(type,dec) \
  175. \
  176. class dec TREE_OF(type) : public TREE \
  177. { \
  178. private: \
  179. static BOOL _fDelProp; \
  180. \
  181. public: \
  182. TREE_OF(type) ( type * const pelem ) : ( (VOID *) pelem ) \
  183. { _fDelProp = FALSE; } \
  184. \
  185. ~TREE_OF(type)() \
  186. { \
  187. if ( _fDelProp ) \
  188. { \
  189. type * _prop = (type *) TREE::QueryProp(); \
  190. delete _prop; \
  191. } \
  192. \
  193. /* pttmp is used because pt's right pointer is set to
  194. * NULL on the delete, so we cache it in pttmp
  195. */ \
  196. TREE_OF(type) *pt = QueryFirstSubtree(), *pttmp; \
  197. while ( pt != NULL ) \
  198. { \
  199. pttmp = pt->QueryRight(); \
  200. delete pt; \
  201. pt = pttmp; \
  202. } \
  203. \
  204. } \
  205. \
  206. VOID Clear() \
  207. { \
  208. _fDelProp = TRUE; \
  209. delete this; \
  210. _fDelProp = FALSE; \
  211. } \
  212. \
  213. type * QueryProp() const \
  214. { return (type *)TREE::QueryProp(); } \
  215. \
  216. VOID SetProp( type * pelem ) \
  217. { TREE::SetProp( (VOID *) pelem ); } \
  218. \
  219. TREE_OF(type)* QueryParent() const \
  220. { return (TREE_OF(type) *) TREE::QueryParent(); } \
  221. \
  222. TREE_OF(type)* QueryLeft() const \
  223. { return (TREE_OF(type) *) TREE::QueryLeft(); } \
  224. \
  225. TREE_OF(type) * QueryRight() const \
  226. { return (TREE_OF(type) *) TREE::QueryRight(); } \
  227. \
  228. TREE_OF(type) * QueryFirstSubtree() const \
  229. { return (TREE_OF(type) *) TREE::QueryFirstSubtree(); } \
  230. \
  231. TREE_OF(type) * QueryLastSubtree() const \
  232. { return (TREE_OF(type) *) TREE::QueryLastSubtree(); } \
  233. \
  234. VOID JoinSubtreeLeft( TREE * ptree ) \
  235. { TREE::JoinSubtreeLeft( (TREE *) ptree ); } \
  236. \
  237. VOID JoinSubtreeRight( TREE * ptree ) \
  238. { TREE::JoinSubtreeRight( (TREE *) ptree ); } \
  239. \
  240. VOID JoinSiblingLeft( TREE * ptree ) \
  241. { TREE::JoinSiblingLeft( (TREE *) ptree ); } \
  242. \
  243. VOID JoinSiblingRight( TREE * ptree ) \
  244. { TREE::JoinSiblingRight( (TREE *) ptree ); } \
  245. \
  246. TREE_OF(type)* BreakOut() \
  247. { return (TREE_OF(type) *) TREE::BreakOut(); } \
  248. };
  249. #define DECLARE_TREE_OF(type) \
  250. DECL_TREE_OF(type,DLL_TEMPLATE)
  251. #endif // _TREE_HXX_