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.

220 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: linklist.hxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. Microsoft OS/2 LAN Manager
  12. Copyright(c) Microsoft Corp., 1990
  13. RPC locator - Written by Steven Zeck
  14. This file contains a linked list class definition.
  15. This base class for Link and Item just contains a set of
  16. two pointers. Derived classes are created with the
  17. macros LinkList or LinkListClass (used for nested inheritance).
  18. These derived classes take your member data items and add them
  19. to the base class.
  20. If you define a macro ASSERT_VCLASS/ASSERT_CLASS, then you must
  21. define a member method Assert for each class you derived which checks
  22. the runtime data consistance of the members you have added.
  23. -------------------------------------------------------------------- */
  24. #ifndef _LINKLIST_
  25. #define _LINKLIST_
  26. #ifndef ASSERT_VCLASS
  27. #define ASSERT_CLASS void Assert() {(void)(0);}
  28. #define ASSERT_VCLASS ASSERT_CLASS
  29. #endif
  30. class LinkItem { // Linked list Item (LI) class *&
  31. private:
  32. LinkItem *pLINext; // Next and Previous Nodes
  33. LinkItem *pLIPrev;
  34. public:
  35. friend class LinkList;
  36. ASSERT_VCLASS;
  37. LinkItem *Next( // return the Next element on the list
  38. ) {
  39. return (pLINext);
  40. }
  41. void Remove(LinkList& pLLHead); // delete a LI from a LinkList
  42. };
  43. class LinkList { // A Linked List (LL) class *&
  44. friend class LinkItem;
  45. private:
  46. LinkItem *pLIHead; // Head of list
  47. LinkItem *pLITail; // Tail of list
  48. public:
  49. ASSERT_CLASS;
  50. LinkList( // constructure for a new LL
  51. ) {
  52. pLIHead = pLITail = Nil;
  53. }
  54. void Add(LinkItem *pLInew); // Add new item item at head of list
  55. void Append(LinkItem *pLInew); // Append new item item at end of list
  56. LinkItem *First( // return the First element on the list
  57. ) {
  58. this->Assert();
  59. return (pLIHead);
  60. }
  61. };
  62. // This macro is used to dervive a linked list from an existing class
  63. // This is a way to do multiple inheritance before C++ 2.0
  64. #define LINK_LIST_DERVIVED(CLASS, DERVIVED, MEMBERS) \
  65. \
  66. class CLASS: public DERVIVED { \
  67. \
  68. private: \
  69. CLASS *pLINext; \
  70. CLASS *pLIPrev; \
  71. \
  72. MEMBERS \
  73. public: \
  74. friend class CLASS##List; \
  75. ASSERT_VCLASS; \
  76. \
  77. CLASS *Next( \
  78. ) { \
  79. return ((pLINext)? (CLASS *) ((char *)pLINext - \
  80. (int) &(((CLASS *) 0)->pLINext) ): Nil); \
  81. } \
  82. \
  83. void Remove(CLASS##List& pLLHead) { \
  84. ((LinkItem *)(&this->pLINext))->LinkItem::Remove(*(LinkList *) &pLLHead); \
  85. } \
  86. }; \
  87. \
  88. class CLASS##List { \
  89. \
  90. friend class CLASS; \
  91. \
  92. private: \
  93. \
  94. CLASS *pLIHead; \
  95. CLASS *pLITail; \
  96. public: \
  97. \
  98. ASSERT_CLASS; \
  99. \
  100. CLASS##List( \
  101. ) { \
  102. pLIHead = pLITail = Nil; \
  103. } \
  104. \
  105. CLASS * Add(CLASS *pLInew) { \
  106. ((LinkList *)(&this->pLIHead))->Add((LinkItem *) &pLInew->pLINext); \
  107. return(pLInew); \
  108. } \
  109. CLASS * Append(CLASS *pLInew) { \
  110. ((LinkList *)(&this->pLIHead))->Append((LinkItem *) &pLInew->pLINext); \
  111. return(pLInew); \
  112. } \
  113. \
  114. CLASS *First( \
  115. ) { \
  116. this->Assert(); \
  117. return ((pLIHead)? (CLASS *) ((char *)pLIHead - \
  118. (int) &(((CLASS *) 0)->pLINext) ): Nil); \
  119. } \
  120. }; \
  121. #define ToItem(TYPE, arg) ((TYPE##Item *) ((char *)arg-sizeof(LinkList)))
  122. // Include NIL_NEW, if you want Add/Append with default NEW constructors
  123. #define NIL_NEW \
  124. \
  125. CLASS_PREFIX##Item *Add() { \
  126. \
  127. CLASS_PREFIX##Item *pLLI = new CLASS_PREFIX##Item; \
  128. if (pLLI != 0) \
  129. LinkList::Add(pLLI); \
  130. return (pLLI); \
  131. } \
  132. \
  133. \
  134. CLASS_PREFIX##Item *Append() { \
  135. \
  136. CLASS_PREFIX##Item *pLLI = new CLASS_PREFIX##Item; \
  137. if (pLLI != 0) \
  138. LinkList::Append(pLLI); \
  139. return (pLLI); \
  140. } \
  141. \
  142. //** This macro defines a instance of a linklist item **//
  143. #define LINK_LIST(CLASS_PREFIX, MEMBERS) LINK_LIST_CLASS(CLASS_PREFIX, Link, MEMBERS)
  144. #define LINK_LIST_CLASS(CLASS_PREFIX, BASE, MEMBERS) \
  145. \
  146. class CLASS_PREFIX##List; \
  147. \
  148. class CLASS_PREFIX##Item:public BASE##Item { \
  149. \
  150. public: \
  151. \
  152. CLASS_PREFIX##Item *Next( \
  153. ) { \
  154. this->Assert(); \
  155. return ((CLASS_PREFIX##Item *)(this->LinkItem::Next())); \
  156. } \
  157. \
  158. /* Put an ASSERT_VCLASS in MEMBERS if desired */ \
  159. \
  160. MEMBERS \
  161. \
  162. }; \
  163. \
  164. class CLASS_PREFIX##List:public BASE##List { \
  165. \
  166. public: \
  167. \
  168. CLASS_PREFIX##Item *Add(CLASS_PREFIX##Item *pLLI) { \
  169. \
  170. LinkList::Add(pLLI); \
  171. return (pLLI); \
  172. } \
  173. \
  174. CLASS_PREFIX##Item *Append(CLASS_PREFIX##Item *pLLI) { \
  175. \
  176. LinkList::Append(pLLI); \
  177. return (pLLI); \
  178. } \
  179. \
  180. \
  181. CLASS_PREFIX##Item *First( \
  182. ) { \
  183. return ((CLASS_PREFIX##Item *)LinkList::First()); \
  184. } \
  185. \
  186. \
  187. };
  188. #endif // _LINKLIST_
  189.