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.

540 lines
16 KiB

  1. /****************************************************************************/
  2. /** Microsoft OS/2 LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990 **/
  4. /****************************************************************************/
  5. /****************************************************************************\
  6. dlist.hxx
  7. LM 3.0 Generic dlist packackage
  8. This header file contains a generic dlist macro that can be used to
  9. create an efficient doubly 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_DLIST_OF(DUMB) // or DECLARE_EXT_DLIST_OF(DUMB)
  20. DLIST_OF(DUMB) dumDlist ;
  21. ITER_DL_OF( DUMB ) iterDum( dumDlist ) ;
  22. RITER_DL_OF(DUMB ) riterDum(dumDlist ) ;
  23. main()
  24. {
  25. dumDlist.Add( new DUMB( SomeData ) ) ;
  26. while ( ( pd = iterDum.Next() ) != NULL )
  27. pd->DoSomething() ;
  28. }
  29. SUGGESTIONS FOR MODIFICATION:
  30. FILE HISTORY:
  31. johnl 23-Jul-1990 Created
  32. johnl 16-Oct-1990 Changes as per Peterwi's requests
  33. johnl 31-Oct-1990 Updated to reflect new iter. functionality
  34. johnl 7-Mar-1991 Code review changes
  35. KeithMo 23-Oct-1991 Added forward references.
  36. \****************************************************************************/
  37. #ifndef _DLIST_HXX_
  38. #define _DLIST_HXX_
  39. // DebugPrint() declaration macro.
  40. #if defined(DEBUG)
  41. #define DBG_PRINT_DLIST_IMPLEMENTATION { _DebugPrint(); }
  42. #else
  43. #define DBG_PRINT_DLIST_IMPLEMENTATION { ; }
  44. #endif
  45. #define DECLARE_DBG_PRINT_DLIST \
  46. void _DebugPrint () const ; \
  47. void DebugPrint () const DBG_PRINT_DLIST_IMPLEMENTATION
  48. //
  49. // Forward references.
  50. //
  51. DLL_CLASS DL_NODE;
  52. DLL_CLASS ITER_DL;
  53. DLL_CLASS ITER_L;
  54. DLL_CLASS DLIST;
  55. DLL_CLASS RITER_DL;
  56. /****************************************************************************\
  57. *
  58. *NAME DL_NODE
  59. *
  60. *WORKBOOK: DL_NODE
  61. *
  62. *SYNOPSIS: Storage class for the DLIST type
  63. *
  64. \****************************************************************************/
  65. DLL_CLASS DL_NODE
  66. {
  67. friend class ITER_DL ;
  68. public:
  69. DL_NODE( DL_NODE *Prev, DL_NODE *Next, void * pelem )
  70. { Set( Prev, Next, pelem ) ; }
  71. void Set( DL_NODE *Prev, DL_NODE *Next, void * pelem )
  72. {
  73. _pelem = pelem ;
  74. _pdlnodeNext = Next ;
  75. _pdlnodePrev = Prev ;
  76. }
  77. DL_NODE *_pdlnodeNext, *_pdlnodePrev ; /* Links in DLIST */
  78. void *_pelem ; /* Pointer to element */
  79. } ;
  80. /****************************************************************************\
  81. *
  82. *NAME: ITER_L
  83. *
  84. *WORKBOOK: ITER_L
  85. *
  86. *SYNOPSIS: Abstract list iterator class for ITER_DL & RITER_DL
  87. *
  88. *INTERFACE: void * vNext() - Returns the next item or NULL
  89. *
  90. *NOTES: This guy was created so some code for ITER_DL & RITER_DL
  91. * could be shared (that polymorphous thang). We couldn't use
  92. * the ITER defn. from iter.hxx because of the semi-parameterized
  93. * nature of the DLIST class (see discussion under ITER_DL).
  94. *
  95. * C++ doesn't allow you to overload on the return type of a method.
  96. * Ideally, what we would want is (in an inheritance tree):
  97. *
  98. * 0. ITER_L ( void * vNext() )
  99. * 1. ITER_DL RITER_DL ( void * vNext() )
  100. * 2. ITER_DL_JUNK RITER_DL_JUNK ( JUNK *Next() )
  101. *
  102. * The user would then be free to create ITER_L *'s and treat all
  103. * ITERs in the same way. The generic approach however requires
  104. * the upper levels of the tree (Level 1) to operate with void
  105. * pointers, thus when you try and parametrize the virtual method
  106. * and tell it to return a JUNK * (as opposed to a void *) the
  107. * compiler complains because the return type for the virtual
  108. * method is different. Thus in this interface, the virtual
  109. * method is called vNext (which returns a void *), and is cast
  110. * to the appropriate parameterized type at level 2. You could
  111. * use the virtual method vNext if you needed to mix iterators
  112. * and cast it yourself. We are not publicizing this use however
  113. * because it probably will not occur.
  114. *
  115. * The _pdlnodeCurrent always points to an slist node except when
  116. * the list is empty or the iterator is at the end of the list.
  117. *
  118. * The _fUsed member is a flag which tells the iterator whether or
  119. * not to go to the next node (it doesn't move till it has been
  120. * used once, thus the name _fUsed).
  121. *
  122. *HISTORY: johnl 25-jul-90 Created
  123. *
  124. *
  125. *
  126. \****************************************************************************/
  127. DLL_CLASS ITER_L
  128. {
  129. friend class DLIST ;
  130. public:
  131. virtual void* vNext( void ) = 0 ;
  132. void * QueryProp( void )
  133. {
  134. return (_pdlnodeCurrent != NULL ? _pdlnodeCurrent->_pelem : NULL ) ;
  135. }
  136. protected:
  137. DL_NODE * _pdlnodeCurrent ; /* Pointer to current node */
  138. DLIST * _pdlist ; /* Pointer to DLIST this iter belongs */
  139. BOOL _fUsed ; /* Has been used flag */
  140. ITER_L * _pdliterNext ;
  141. };
  142. /****************************************************************************\
  143. *
  144. *NAME: ITER_DL
  145. *
  146. *WORKBOOK: ITER_DL, RITER_DL
  147. *
  148. *SYNOPSIS: Forward/Reverse iterator for the DLIST class
  149. * The iterator "points" to the element that was just returned by
  150. * vNext.
  151. *INTERFACE:
  152. * ITER_DL( ) - Constructor
  153. * ITER_DL( ) - Contructor w/ no position at iterdl
  154. * ~ITER_DL() ; - Destructor
  155. * void Reset( ) - Reset the iterator to its initial state
  156. * void* operator()() - Synonym for next
  157. * void* vNext( ) ; - Goto the next element in the list
  158. * void* QueryProp( )- Returns the current property this iterator
  159. * is pointing to
  160. *
  161. *PARENT:
  162. *
  163. *USES:
  164. *
  165. *CAVEATS: Even though ITER_L is a base object, you cannot create an array
  166. * of ITER * and use this interface. See NOTES below.
  167. *
  168. *HISTORY: johnl 07-25-90 Created
  169. *
  170. \****************************************************************************/
  171. DLL_CLASS ITER_DL : public ITER_L
  172. {
  173. friend class DLIST ;
  174. friend class ITER_DL ;
  175. public:
  176. ITER_DL( DLIST * pdl ) ;
  177. ITER_DL( const ITER_DL& iterdl ) ;
  178. ~ITER_DL() ;
  179. void Reset( void ) ;
  180. void* vNext( void ) ;
  181. };
  182. DLL_CLASS RITER_DL : public ITER_L
  183. {
  184. friend class DLIST ;
  185. friend class RITER_DL ;
  186. public:
  187. RITER_DL( DLIST * pdl ) ;
  188. RITER_DL( const RITER_DL& riterdl ) ;
  189. ~RITER_DL() ;
  190. void Reset( void ) ;
  191. void* vNext( void ) ;
  192. };
  193. /****************************************************************************\
  194. *
  195. *NAME: DLIST
  196. *
  197. *WORKBOOK: DLIST
  198. *
  199. *SYNOPSIS: Parameterized DLIST implementation
  200. *
  201. *INTERFACE: DECLARE_DLIST_OF() - Produces a declaration for a dlist
  202. * of itemtype.
  203. *
  204. * DECLARE_EXT_DLIST_OF() - Produces a declaration for a dlist
  205. * of itemtype, with the addition of
  206. * a couple more methods (Remove, IsMember)
  207. *
  208. * DLIST_OF() dlMylist ;- Declares a dlist of itemtype called
  209. * dlMylist
  210. *
  211. * ITER_DL_OF(itemtype) iterdlType() ;
  212. * - Declares a forward iterator for dlMyList
  213. *
  214. * ITER_DL_OF(itemtype) iterdlType() ;
  215. * - Declares forward iterator at the passed
  216. * iterator
  217. *
  218. * RITER_DL_OF(itemtype) riterdlType() ;
  219. * - Declares a reverse iterator for dlMyList
  220. *
  221. * RITER_DL_OF(itemtype) riterdlType() ;
  222. * - Declares a reverse iterator at the passed
  223. * iterator
  224. *
  225. * Clear() - Specifically delete all elements in the
  226. * dlist (code is in macro expansion)
  227. *
  228. * QueryNumElem( ) - Returns the number of elements
  229. * in the dlist.
  230. *
  231. * Add( ) - Makes a copy of element e
  232. * and adds it as the next element in the dlist.
  233. *
  234. * Append( ) - Makes a copy of element e
  235. * and adds it at the end of the dlist.
  236. *
  237. * Insert( ) - Makes a copy of element e and adds it to the
  238. * "left" of the passed iterator.
  239. *
  240. * Remove( ) - Removes the element to the left of
  241. * the passed iter and returns the element.
  242. *
  243. *
  244. * Remove( ) - Finds element e and
  245. * removes it from the list, returning the item.
  246. * (only defined when using DECLARE_EXT_DLIST_OF())
  247. *
  248. * IsMember( ) - Returns true if the element belongs to the
  249. * dlist.
  250. * (only defined when using DECLARE_EXT_DLIST_OF())
  251. *
  252. *
  253. * private:
  254. *
  255. * BumpIters( ) - For any iterators pointing to the passed
  256. * iter node, BumpIters calls iter.Next(). Used when deleting
  257. * an item from the list.
  258. *
  259. * Register( ) - Registers an iterator with the dlist
  260. *
  261. * Deregister( ) - Deregisters an iterator with the dlist
  262. *
  263. * SetIters( ) - Sets all registered iters to the
  264. * passed value.
  265. *
  266. * Unlink() - Removes the passed DL_NODE from the dlist. Returns
  267. * the properties pointer or NULL if not found. The
  268. * DL_NODE is deleted.
  269. *
  270. *
  271. *PARENT: LIST
  272. *
  273. *USES:
  274. *
  275. *CAVEATS:
  276. *
  277. *HISTORY:
  278. * Johnl 28-Jun-1990 Created
  279. * Johnl 12-Jul-1990 Made iters safe for deleting
  280. * Johnl 16-Oct-1990 Moved Clear to macro expansion
  281. * (so it can access dest. of object)
  282. * KeithMo 09-Oct-1991 Win32 Conversion.
  283. *
  284. \****************************************************************************/
  285. DLL_CLASS DLIST
  286. {
  287. friend class ITER_DL ;
  288. friend class RITER_DL ;
  289. public:
  290. DLIST( ) ;
  291. ~DLIST() ;
  292. // void Clear( void ) ; <<-- Defined in macro expansion
  293. UINT QueryNumElem( void ) ;
  294. APIERR Add( void * pelem ) ;
  295. APIERR Append( void * pelem ) ;
  296. APIERR Insert( void * pelem, ITER_DL& dliter ) ;
  297. APIERR Insert( void * pelem, RITER_DL& dlriter ) ;
  298. void * Remove( ITER_DL& dliter ) ;
  299. void * Remove( RITER_DL& dlriter ) ;
  300. DECLARE_DBG_PRINT_DLIST
  301. protected:
  302. DL_NODE *_pdlHead, *_pdlTail ; /* Head and Tail of DLIST */
  303. ITER_L *_pdliterRegisteredIters ; /* Pointer to list of registered iters. */
  304. protected:
  305. void Register( ITER_L * pdliter ) ;
  306. void Deregister( ITER_L * pdliter ) ;
  307. void BumpIters( DL_NODE *pdlnode ) ;
  308. void SetIters( DL_NODE *pdlnode ) ;
  309. BOOL CheckIter( ITER_L *pdliter ) ;
  310. void * Unlink( DL_NODE * pdlnodeTarget ) ;
  311. } ;
  312. /**********************************************************************\
  313. NAME: DECLARE_DLIST_OF( type )
  314. SYNOPSIS: Macro that expands into the type specific portions of the
  315. DLIST package. The difference between DECLARE_DLIST_OF and
  316. DECLARE_EXT_DLIST_OF is that DECLARE_EXT_DLIST_OF defines
  317. additional methods. Specifically:
  318. Remove( ) - Find and remove element e from the dlist
  319. IsMember( ) - Returns TRUE if item e is in the dlist
  320. NOTES: Other helper macros are:
  321. DLIST_OF( type ) - for declaring DLIST lists
  322. ITER_DL_OF(type) - for declaring Forward iterators
  323. RITER_DL_OF(type) - for declaring reverse iterators
  324. See the beginning of this file for usage of this package.
  325. HISTORY: johnl 24-Jul-90 Created
  326. johnl 15-Oct-90 Broke out Remove & IsMember to be
  327. conditional on the symbol EXTENDED_DL
  328. \**********************************************************************/
  329. #define DLIST_OF(type) DLIST_OF_##type
  330. #define ITER_DL_OF(type) ITER_DL_##type
  331. #define RITER_DL_OF(type) RITER_DL_##type
  332. #define DECL_DLIST_OF(type,dec) \
  333. class dec DLIST_OF(type) ; \
  334. \
  335. class dec ITER_DL_OF(type) : public ITER_DL \
  336. { \
  337. public: \
  338. ITER_DL_OF(type)( DLIST& dl ) : ITER_DL(&dl) { ; } \
  339. ITER_DL_OF(type)( const ITER_DL_OF(type)& iterdl ) \
  340. : ITER_DL(iterdl ) { ; } \
  341. ~ITER_DL_OF(type)() { ; } \
  342. \
  343. inline type* Next( void ) \
  344. { \
  345. return (type *)ITER_DL::vNext() ; \
  346. } \
  347. inline type* operator()(void) { return (type *) Next(); } \
  348. \
  349. inline type* QueryProp( void ) { return (type *)ITER_L::QueryProp() ; } \
  350. }; \
  351. \
  352. class dec RITER_DL_OF(type) : public RITER_DL \
  353. { \
  354. public: \
  355. RITER_DL_OF(type)( DLIST& dl ) : RITER_DL(&dl) { ; } \
  356. RITER_DL_OF(type)( const RITER_DL_OF(type)& riterdl ) \
  357. : RITER_DL(riterdl) { ; } \
  358. ~RITER_DL_OF(type)() { ; } \
  359. \
  360. inline type* Next( void ) \
  361. { \
  362. return (type *)RITER_DL::vNext() ; \
  363. } \
  364. inline type* operator()(void) { return (type *) Next(); } \
  365. \
  366. inline type* QueryProp( void ) { return (type *)ITER_L::QueryProp() ; } \
  367. \
  368. }; \
  369. \
  370. class dec DLIST_OF(type) : public DLIST \
  371. { \
  372. private: \
  373. BOOL _fDestroy; \
  374. \
  375. public: \
  376. DLIST_OF(type) ( BOOL fDestroy = TRUE ) \
  377. : _fDestroy( fDestroy ) \
  378. { ; } \
  379. ~DLIST_OF(type)() { Clear() ; } \
  380. \
  381. void Clear( void ) \
  382. { \
  383. register DL_NODE *_pdlnode = _pdlHead, *_pdlnodeOld = NULL ; \
  384. \
  385. while ( _pdlnode != NULL ) \
  386. { \
  387. _pdlnodeOld = _pdlnode ; \
  388. _pdlnode = _pdlnode->_pdlnodeNext ; \
  389. if ( _fDestroy ) \
  390. delete ((type *)_pdlnodeOld->_pelem) ; \
  391. delete _pdlnodeOld ; \
  392. } \
  393. _pdlHead = _pdlTail = NULL ; \
  394. \
  395. SetIters( NULL ) ; \
  396. } \
  397. \
  398. \
  399. inline APIERR Add( type* const pelem ) \
  400. { \
  401. return DLIST::Add( (void *)pelem ) ; \
  402. } \
  403. \
  404. inline APIERR Append( type* const pelem ) \
  405. { \
  406. return DLIST::Append( (void *)pelem ) ; \
  407. } \
  408. \
  409. inline APIERR Insert( type * pelem, ITER_DL_OF(type)& dliter ) \
  410. { \
  411. return DLIST::Insert( (void *)pelem, dliter ) ; \
  412. } \
  413. \
  414. inline APIERR Insert( type* pelem, RITER_DL_OF(type)& riterdl ) \
  415. { \
  416. return DLIST::Insert( (void *)pelem, riterdl ) ; \
  417. } \
  418. \
  419. inline type* Remove( ITER_DL_OF(type)& iterdl ) \
  420. { \
  421. return (type *) DLIST::Remove( iterdl ) ; \
  422. } \
  423. \
  424. inline type* Remove( RITER_DL_OF(type)& riterdl ) \
  425. { \
  426. return (type *) DLIST::Remove( riterdl ) ; \
  427. } \
  428. \
  429. /* The following can only be used if you use the extended DLIST */ \
  430. type* Remove( const type& e ) ; \
  431. BOOL IsMember( const type& e ) ; \
  432. \
  433. } ; //DECLARE_DLIST_OF(type)
  434. #define DECL_EXT_DLIST_OF(type,dec) \
  435. DECL_DLIST_OF(type,dec) \
  436. type * DLIST_OF(type)::Remove( const type& e ) \
  437. { \
  438. register DL_NODE *_pdlnode = _pdlHead ; \
  439. \
  440. while ( _pdlnode != NULL ) \
  441. { \
  442. if ( !((type *)_pdlnode->_pelem)->Compare( &e ) ) \
  443. return (type *) Unlink( _pdlnode ) ; \
  444. else \
  445. _pdlnode = _pdlnode->_pdlnodeNext ; \
  446. } \
  447. \
  448. return (type *) NULL ; \
  449. } \
  450. \
  451. BOOL DLIST_OF(type)::IsMember( const type& e ) \
  452. { \
  453. register DL_NODE *_pdlnode = _pdlHead ; \
  454. \
  455. while ( _pdlnode != NULL ) \
  456. { \
  457. if ( !((type *)_pdlnode->_pelem)->Compare( &e ) ) \
  458. return TRUE ; \
  459. else \
  460. _pdlnode = _pdlnode->_pdlnodeNext ; \
  461. } \
  462. \
  463. return FALSE ; \
  464. }
  465. // Helper macros for code preservation
  466. #define DECLARE_DLIST_OF(type) \
  467. DECL_DLIST_OF(type,DLL_TEMPLATE)
  468. #define DECLARE_EXT_DLIST_OF(type) \
  469. DECL_EXT_DLIST_OF(type,DLL_TEMPLATE)
  470. #endif // _DLIST_HXX_