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.

159 lines
4.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: gelmwalk.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // gelmwalk.h
  12. //
  13. #ifndef _GELMWALK_H_
  14. #define _GELMWALK_H_
  15. #include "gelem.h"
  16. // Control structure
  17. struct EWALKCTL
  18. {
  19. int _bBreadth : 1; // Breath-first or Depth-first
  20. int _bAscend : 1; // Up or down
  21. int _bInvert : 1; // Normal order or backwards
  22. };
  23. ////////////////////////////////////////////////////////////////////
  24. // class GRPHWALK: Generalize walk-a-graph class.
  25. //
  26. // Subclass and declare BSelect() and BMark().
  27. // BSelect() is called to decide if a node should be followed.
  28. // BMark() is called to perform unique work on the node. If
  29. // it returns false, walk is terminated immediately.
  30. //
  31. ////////////////////////////////////////////////////////////////////
  32. class GRPHWALK
  33. {
  34. public:
  35. GRPHWALK ( GNODE * pnodeStart, EWALKCTL ectl )
  36. : _pnodeStart(pnodeStart),
  37. _ectl(ectl)
  38. {}
  39. ~ GRPHWALK() {}
  40. void Walk ()
  41. {
  42. if ( _ectl._bBreadth )
  43. BBreadthFirst( _pnodeStart );
  44. else
  45. BDepthFirst( _pnodeStart );
  46. }
  47. protected:
  48. GNODE * _pnodeStart; // Point of origin
  49. EWALKCTL _ectl; // Type, ordering and direction flags
  50. protected:
  51. // Return true if this node should be followed
  52. virtual bool BSelect ( GNODE * pnode ) = 0;
  53. // Mark/fiddle with the node; return false if enumeration should end
  54. virtual bool BMark ( GNODE * pnode ) = 0;
  55. bool BDepthFirst ( GNODE * pnode );
  56. bool BBreadthFirst ( GNODE * pnode );
  57. };
  58. ////////////////////////////////////////////////////////////////////
  59. // template GRPHWALKER:
  60. // Template for generating walk-a-graph routines
  61. ////////////////////////////////////////////////////////////////////
  62. template <class GND>
  63. class GRPHWALKER : public GRPHWALK
  64. {
  65. public:
  66. GRPHWALKER ( GND * pnodeStart, EWALKCTL ectl );
  67. // You must write your own variants of these
  68. virtual bool BSelect ( GND * pnode );
  69. virtual bool BMark ( GND * pnode );
  70. protected:
  71. // Type-safe redirectors for derived base types.
  72. virtual bool BSelect ( GNODE * pnode )
  73. { return BSelect( (GND *) pnode ); }
  74. virtual bool BMark ( GNODE * pnode )
  75. { return BMark( (GND *) pnode ); }
  76. };
  77. ////////////////////////////////////////////////////////////////////
  78. ////////////////////////////////////////////////////////////////////
  79. // Inline member functions
  80. ////////////////////////////////////////////////////////////////////
  81. ////////////////////////////////////////////////////////////////////
  82. inline
  83. bool GRPHWALK :: BDepthFirst ( GNODE * pnode )
  84. {
  85. GNODENUM<GNODE> itnd( _ectl._bAscend, _ectl._bInvert );
  86. for ( ; itnd.PnodeCurrent(); itnd++ )
  87. {
  88. GNODE * pnode2 = *itnd;
  89. if ( BSelect( pnode2 ) )
  90. {
  91. if ( ! BMark( pnode2 ) )
  92. return false;
  93. BDepthFirst( pnode2 );
  94. }
  95. }
  96. return true;
  97. }
  98. inline
  99. bool GRPHWALK :: BBreadthFirst ( GNODE * pnode )
  100. {
  101. VPGNODE vpnodeA;
  102. VPGNODE vpnodeB;
  103. VPGNODE * pvThis = & vpnodeA;
  104. VPGNODE * pvNext = & vpnodeB;
  105. VPGNODE * pvTemp = NULL;
  106. // Seed the arrays with the starting position
  107. pvNext->push_back(pnode);
  108. // Create the reusable enumerator
  109. GNODENUM<GNODE> itnd( _ectl._bAscend, _ectl._bInvert );
  110. while ( pvNext->size() > 0)
  111. {
  112. // Swap the arrays from the last cycle and this cycle
  113. pvTemp = pvThis;
  114. pvThis = pvNext;
  115. pvNext = pvTemp;
  116. pvNext->clear();
  117. // Walk all descendents at this level and expand the next level
  118. // into the secondary array
  119. for ( INT iThis = 0; iThis < pvThis->size(); iThis++ )
  120. {
  121. GNODE * pnode = (*pvThis)[iThis];
  122. for ( itnd.Set( pnode ); itnd.PnodeCurrent(); itnd++ )
  123. {
  124. GNODE * pnode2 = *itnd;
  125. if ( BSelect( pnode2 ) )
  126. {
  127. if ( ! BMark( pnode2 ) )
  128. return false;
  129. pvNext->push_back(pnode2);
  130. }
  131. }
  132. }
  133. }
  134. return true;
  135. }
  136. #endif //