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

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. slist.hxx
  7. LM 3.0 Generic slist package
  8. This header file contains a generic list "macro" that can be used to
  9. create an efficient singly linked list implementation for any type.
  10. USAGE:
  11. class DUMB
  12. {
  13. [...]
  14. public:
  15. int Compare( const DUMB * pd )
  16. { return (( _i == pd->_i ) ? 0 : (( _i < pd->_i ) ? -1 : 1 ) ); }
  17. [...]
  18. };
  19. DECLARE_SLIST_OF(DUMB)
  20. DEFINE_SLIST_OF(DUMB) // or DEFINE_EXT_SLIST_OF(DUMB)
  21. SLIST_OF(DUMB) dumSlist;
  22. ITER_SL_OF( DUMB ) iterDum( dumSlist );
  23. main()
  24. {
  25. DUMB *pd;
  26. pd = new DUMB( somedata );
  27. dumSlist.Add( pd );
  28. while ( ( pd = iterDum.Next() ) != NULL )
  29. pd->DoSomething();
  30. }
  31. To use an SLIST in a class definition, then do something like:
  32. ----------- MyHeader.hxx ----------
  33. //#include <slist.hxx>
  34. DECLARE_SLIST_OF(DUMB)
  35. class MYCLASS
  36. {
  37. private:
  38. SLIST_OF( DUMB ) _slDumb;
  39. ...
  40. };
  41. ----------- MyHeader.cxx ----------
  42. //#include <slist.hxx>
  43. //#include <MyHeader.hxx>
  44. DEFINE_SLIST_OF(DUMB);
  45. ...
  46. -----------------------------------
  47. FILE HISTORY:
  48. johnl 28-Jun-1990 Created
  49. johnl 24-Jul-1990 Changed to use slist.cxx
  50. johnl 11-Oct-1990 Only keeps pointers in Slist (doesn't copy)
  51. johnl 30-Oct-1990 Made functional changes as per Peterwi's requests
  52. (Iter doesn't advance, added some funct. to
  53. internal nodes etc.)
  54. johnl 7-Mar-1991 Code review changes
  55. Johnl 9-Jul-1991 Broke SLIST into define and declare components
  56. beng 26-Sep-1991 Removed LM_2 versions
  57. KeithMo 23-Oct-1991 Added forward references.
  58. */
  59. #ifndef _SLIST_HXX_
  60. #define _SLIST_HXX_
  61. // DebugPrint() declaration macro.
  62. #if defined(DEBUG)
  63. #define DBG_PRINT_SLIST_IMPLEMENTATION { _DebugPrint(); }
  64. #else
  65. #define DBG_PRINT_SLIST_IMPLEMENTATION { ; }
  66. #endif
  67. #define DECLARE_DBG_PRINT_SLIST \
  68. void _DebugPrint () const ; \
  69. void DebugPrint () const DBG_PRINT_SLIST_IMPLEMENTATION
  70. //
  71. // Forward references.
  72. //
  73. DLL_CLASS SL_NODE;
  74. DLL_CLASS SLIST;
  75. DLL_CLASS ITER_SL;
  76. /*************************************************************************
  77. NAME: SL_NODE
  78. SYNOPSIS: Storage class for the SLIST type
  79. INTERFACE: Set() - stores a pointer in the node
  80. HISTORY:
  81. beng 26-Sep-1991 Header added
  82. **************************************************************************/
  83. DLL_CLASS SL_NODE
  84. {
  85. friend class SLIST;
  86. friend class ITER_SL;
  87. public:
  88. SL_NODE( SL_NODE *pslnode, VOID *pv )
  89. : _pslnodeNext(pslnode), _pelem(pv) { }
  90. VOID Set( SL_NODE *pslnode, VOID *pv )
  91. {
  92. /* Note: we guarantee the node is the last thing set
  93. * (this allows us to do current->Set( current->Next, newelem)
  94. * without trashing ourselves).
  95. */
  96. _pelem = pv;
  97. _pslnodeNext = pslnode;
  98. }
  99. SL_NODE *_pslnodeNext;
  100. VOID * _pelem;
  101. };
  102. /*************************************************************************
  103. NAME: ITER_SL
  104. SYNOPSIS: Forward iterator for the SLIST class
  105. The iterator "points" to the element that would be returned on the
  106. next call to Next.
  107. INTERFACE:
  108. ITER_SL( ) - Constructor
  109. ~ITER_SL() - Destructor
  110. Reset() - Reset the iterator to its initial state
  111. operator()() - Synonym for next
  112. Next() - Goto the next element in the list
  113. QueryProp() - Returns the current property this iterator
  114. is pointing to
  115. USES: SLIST
  116. HISTORY:
  117. johnl 07-25-90 Created
  118. johnl 10-11-90 Added QueryProp (request from Peterwi)
  119. johnl 10-30-90 Removed Queryprop in favor of functional
  120. change in iterator (item returned by next
  121. is the current item).
  122. **************************************************************************/
  123. DLL_CLASS ITER_SL
  124. {
  125. friend class SLIST;
  126. public:
  127. ITER_SL( SLIST *psl );
  128. ITER_SL( const ITER_SL& itersl );
  129. ~ITER_SL();
  130. VOID Reset();
  131. VOID* operator()() { return Next(); }
  132. VOID* Next();
  133. VOID* QueryProp();
  134. private:
  135. SL_NODE *_pslnodeCurrent; // Current item pointer
  136. SLIST *_pslist; // Pointer to slist
  137. BOOL _fUsed; // Flag to bump on first next call or not
  138. ITER_SL *_psliterNext; // Pointer to next registered iterator
  139. };
  140. /*************************************************************************
  141. NAME: SLIST
  142. SYNOPSIS: Parameterized slist implementation
  143. INTERFACE:
  144. DECLARE_SLIST_OF() - Produces a declaration for an slist
  145. of itemtype. Generally used in the header file.
  146. DEFINE_SLIST_OF() - Produces type specific code. Should
  147. be used once in a source file.
  148. DEFINE_EXT_SLIST_OF() - Produces code for an slist of itemtype
  149. with several additional methods
  150. (IsMember, Remove(itemtype)), see below.
  151. SLIST_OF() - Declares an slist of itemtype called
  152. MySlist. If you do not want the
  153. elements automatically deleted
  154. in Clear or on destruction, then
  155. pass FALSE to the constructor (the
  156. fDestroy parameter defaults to TRUE.
  157. ITER_SL_OF() - Declares an slist iterator
  158. for iterating through the slist
  159. Clear() - Specifically delete all elements in the slist.
  160. IsMember() - Returns true if the element belongs to the
  161. slist. NOTE: IS ONLY DEFINED FOR THE EXTENDED
  162. SLIST (i.e., one that has been declared with
  163. the DECLARE_EXT_SLIST_OF macro.
  164. QueryNumElem() - Returns the number of elements
  165. in the slist.
  166. Add() - Adds the passed pointer to an object to the
  167. slist (note, DO NOT ADD NULL POINTERS, Add WILL
  168. Assert out if you do this).
  169. Append() - Adds the passed pointer to the end of the
  170. slist.
  171. Insert() - Adds the passed pointer to the
  172. "left" of the passed iterator.
  173. Remove() - Finds element e and removes it from the list,
  174. returning the item. Is only defined if the
  175. DECLARE_EXT_SLIST_OF macro is used.
  176. USES: ITER_SL
  177. NOTES:
  178. BumpIters() - For any iterators pointing to the passed
  179. iter node, BumpIters calls iter.Next(). Used
  180. when deleting an item from the list.
  181. Register() - Registers an iterator with the slist
  182. Deregister() - Deregisters an iterator with the slist
  183. SetIters() - Sets all registered iters to the
  184. passed value.
  185. SetIters( CompVal, NewVal ) - Changes all registered iterators
  186. that are pointing at SL_NODE CompVal to point to SL_NODE
  187. NewVal (used when playing node games).
  188. HISTORY:
  189. Johnl 28-Jun-1990 Created
  190. Johnl 12-Jul-1990 Made iters safe for deleting
  191. Johnl 24-Jul-1990 Converted to use slist.cxx
  192. KeithMo 09-Oct-1991 Win32 Conversion.
  193. **************************************************************************/
  194. DLL_CLASS SLIST
  195. {
  196. friend class ITER_SL;
  197. public:
  198. SLIST();
  199. ~SLIST();
  200. // VOID Clear(); <<-- Defined in macro expansion
  201. UINT QueryNumElem();
  202. APIERR Add( VOID * pelem );
  203. APIERR Append( VOID * pelem );
  204. APIERR Insert( VOID * pelem, ITER_SL& sliter );
  205. VOID* Remove( ITER_SL& sliter );
  206. DECLARE_DBG_PRINT_SLIST
  207. protected:
  208. SL_NODE *_pslHead, *_pslTail;
  209. ITER_SL *_psliterRegisteredIters; // Pointer to list of registered iters
  210. protected:
  211. VOID Register( ITER_SL * psliter );
  212. VOID Deregister( ITER_SL * psliter );
  213. VOID BumpIters( SL_NODE * pslnode );
  214. VOID SetIters( SL_NODE * pslnode );
  215. VOID SetIters( SL_NODE * CompVal, SL_NODE *NewVal );
  216. BOOL CheckIter( ITER_SL * psliter );
  217. SL_NODE* FindPrev( SL_NODE * pslnode );
  218. };
  219. /*************************************************************************
  220. NAME: DECLARE_SLIST_OF
  221. SYNOPSIS: Macro which expands into the type-specific portions of
  222. the SLIST package.
  223. NOTES:
  224. The user can also use:
  225. SLIST_OF( type ) - for declaring SLIST lists
  226. ITER_SL_OF(type) - for declaring Forward iterators
  227. See the beginning of this file for usage of this package.
  228. HISTORY:
  229. johnl 24-Jul-90 Created
  230. beng 30-Apr-1991 New syntax for constructor inheritance
  231. **************************************************************************/
  232. #define SLIST_OF(type) SLIST_OF_##type
  233. #define ITER_SL_OF(type) ITER_SL_##type
  234. /*------ SLIST Macro expansion -------*/
  235. #define DECL_SLIST_OF(type,dec) \
  236. class dec SLIST_OF(type); \
  237. \
  238. class dec ITER_SL_OF(type) : public ITER_SL \
  239. { \
  240. public: \
  241. ITER_SL_OF(type)( SLIST& sl ) : ITER_SL(&sl) {; } \
  242. ITER_SL_OF(type)( const ITER_SL_OF(type)& pitersl ) : \
  243. ITER_SL(pitersl) {; } \
  244. \
  245. type* Next() \
  246. { return (type *)ITER_SL::Next(); } \
  247. \
  248. type* operator()(VOID) \
  249. { return Next(); } \
  250. \
  251. type* QueryProp() \
  252. { return (type *)ITER_SL::QueryProp(); } \
  253. }; \
  254. \
  255. class dec SLIST_OF(type) : public SLIST \
  256. { \
  257. private: \
  258. BOOL _fDestroy; \
  259. \
  260. public: \
  261. SLIST_OF(type) ( BOOL fDestroy = TRUE ) : \
  262. SLIST( ), \
  263. _fDestroy(fDestroy) {; } \
  264. \
  265. ~SLIST_OF(type)() { Clear(); } \
  266. \
  267. VOID Clear(); \
  268. \
  269. APIERR Add( const type * pelemNew ) \
  270. { \
  271. return SLIST::Add( (VOID *)pelemNew ); \
  272. } \
  273. \
  274. APIERR Append( const type * pelemNew ) \
  275. { \
  276. return SLIST::Append( (VOID *)pelemNew ) ; \
  277. } \
  278. \
  279. APIERR Insert( const type *pelemNew, ITER_SL_OF(type)& sliter ) \
  280. { \
  281. return SLIST::Insert( (VOID *)pelemNew, sliter ); \
  282. } \
  283. \
  284. type* Remove( ITER_SL_OF(type)& sliter ) \
  285. { \
  286. return (type *) SLIST::Remove( sliter ); \
  287. } \
  288. \
  289. /* You can only use these */ \
  290. /* if you use DEFINE_EXT_SLIST_OF; otherwise */ \
  291. /* you will get unresolved externals. */ \
  292. type* Remove( type& e ); \
  293. BOOL IsMember( const type& e ); \
  294. };
  295. #define DEFINE_SLIST_OF(type) \
  296. VOID SLIST_OF(type)::Clear() \
  297. { \
  298. register SL_NODE *_pslnode = _pslHead, *_pslnodeOld = NULL; \
  299. \
  300. while ( _pslnode != NULL ) \
  301. { \
  302. _pslnodeOld = _pslnode; \
  303. _pslnode = _pslnode->_pslnodeNext; \
  304. if ( _fDestroy ) \
  305. delete ((type *)_pslnodeOld->_pelem ) ; \
  306. delete _pslnodeOld; \
  307. } \
  308. _pslHead = _pslTail = NULL; \
  309. \
  310. SetIters( NULL ); \
  311. }
  312. #define DEFINE_EXT_SLIST_OF(type) \
  313. DEFINE_SLIST_OF(type) \
  314. \
  315. /* Remove is here so it can see the Compare method of the element */ \
  316. type* SLIST_OF(type)::Remove( type& e ) \
  317. { \
  318. register SL_NODE *_pslnode = _pslHead, *_pslnodePrev = NULL; \
  319. \
  320. while ( _pslnode != NULL ) \
  321. { \
  322. if ( !((type *)_pslnode->_pelem)->Compare( &e ) ) \
  323. { \
  324. if ( _pslnodePrev != NULL ) /* if not first node in list */ \
  325. { \
  326. _pslnodePrev->_pslnodeNext = _pslnode->_pslnodeNext; \
  327. \
  328. /* patch up tail pointer if last item in list */ \
  329. if ( _pslTail == _pslnode ) \
  330. _pslTail = _pslnodePrev; \
  331. } \
  332. else \
  333. if ( _pslnode->_pslnodeNext == NULL ) \
  334. _pslHead = _pslTail = NULL; /* only item in list */ \
  335. else \
  336. _pslHead = _pslnode->_pslnodeNext; \
  337. \
  338. BumpIters( _pslnode ); /* Move iters to next node... */ \
  339. \
  340. type* _pelem = (type *)_pslnode->_pelem; \
  341. delete _pslnode; \
  342. return _pelem; \
  343. } \
  344. else \
  345. { \
  346. _pslnodePrev = _pslnode; \
  347. _pslnode = _pslnode->_pslnodeNext; \
  348. } \
  349. } \
  350. \
  351. return NULL; \
  352. } \
  353. \
  354. BOOL SLIST_OF(type)::IsMember( const type& e ) \
  355. { \
  356. register SL_NODE *_pslnode = _pslHead; \
  357. \
  358. while ( _pslnode != NULL ) \
  359. { \
  360. if ( !((type *)_pslnode->_pelem)->Compare( &e ) ) \
  361. return TRUE; \
  362. else \
  363. _pslnode = _pslnode->_pslnodeNext; \
  364. } \
  365. \
  366. return FALSE; \
  367. }
  368. // Helper macros for code preservation
  369. #define DECLARE_SLIST_OF(type) \
  370. DECL_SLIST_OF(type,DLL_TEMPLATE)
  371. #endif // _SLIST_HXX_