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.

425 lines
11 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. sample\list.h
  5. Abstract:
  6. The file contains a list implementation.
  7. --*/
  8. #ifndef _LIST_H_
  9. #define _LIST_H_
  10. /*++
  11. The Following are already defined
  12. (public\sdk\inc\winnt.h)
  13. //
  14. // Calculate the byte offset of a 'field' in a structure of type 'type'.
  15. //
  16. // #define FIELD_OFFSET(type, field) \
  17. // ((LONG)(LONG_PTR)&(((type *)0)->field))
  18. //
  19. //
  20. // Calculate the address of the base of the structure given its 'type',
  21. // and an 'address' of a 'field' within the structure.
  22. //
  23. // #define CONTAINING_RECORD(address, type, field) \
  24. // ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
  25. //
  26. // Doubly linked list structure.
  27. //
  28. // typedef struct _LIST_ENTRY
  29. // {
  30. // struct _LIST_ENTRY *Flink;
  31. // struct _LIST_ENTRY *Blink;
  32. // } LIST_ENTRY, *PLIST_ENTRY;
  33. //
  34. --*/
  35. //
  36. // Doubly-linked list manipulation routines. Implemented as macros but
  37. // logically these are procedures.
  38. //
  39. //
  40. // VOID
  41. // InitializeListHead(
  42. // PLIST_ENTRY ListHead
  43. // );
  44. //
  45. #define InitializeListHead(ListHead) \
  46. ((ListHead)->Flink = (ListHead)->Blink = (ListHead))
  47. //
  48. // BOOLEAN
  49. // IsListEmpty(
  50. // PLIST_ENTRY ListHead
  51. // );
  52. //
  53. #define IsListEmpty(ListHead) \
  54. ((ListHead)->Flink == (ListHead))
  55. //
  56. // PLIST_ENTRY
  57. // RemoveHeadList(
  58. // PLIST_ENTRY ListHead
  59. // );
  60. //
  61. #define RemoveHeadList(ListHead) \
  62. (ListHead)->Flink; \
  63. {RemoveEntryList((ListHead)->Flink)}
  64. //
  65. // PLIST_ENTRY
  66. // RemoveTailList(
  67. // PLIST_ENTRY ListHead
  68. // );
  69. //
  70. #define RemoveTailList(ListHead) \
  71. (ListHead)->Blink; \
  72. {RemoveEntryList((ListHead)->Blink)}
  73. //
  74. // VOID
  75. // RemoveEntryList(
  76. // PLIST_ENTRY Entry
  77. // );
  78. //
  79. #define RemoveEntryList(Entry) \
  80. { \
  81. PLIST_ENTRY _EX_Blink; \
  82. PLIST_ENTRY _EX_Flink; \
  83. _EX_Flink = (Entry)->Flink; \
  84. _EX_Blink = (Entry)->Blink; \
  85. _EX_Blink->Flink = _EX_Flink; \
  86. _EX_Flink->Blink = _EX_Blink; \
  87. }
  88. //
  89. // VOID
  90. // InsertTailList(
  91. // PLIST_ENTRY ListHead,
  92. // PLIST_ENTRY Entry
  93. // );
  94. //
  95. #define InsertTailList(ListHead,Entry) \
  96. { \
  97. PLIST_ENTRY _EX_Blink; \
  98. PLIST_ENTRY _EX_ListHead; \
  99. _EX_ListHead = (ListHead); \
  100. _EX_Blink = _EX_ListHead->Blink; \
  101. (Entry)->Flink = _EX_ListHead; \
  102. (Entry)->Blink = _EX_Blink; \
  103. _EX_Blink->Flink = (Entry); \
  104. _EX_ListHead->Blink = (Entry); \
  105. }
  106. //
  107. // VOID
  108. // InsertHeadList(
  109. // PLIST_ENTRY ListHead,
  110. // PLIST_ENTRY Entry
  111. // );
  112. //
  113. #define InsertHeadList(ListHead,Entry) \
  114. { \
  115. PLIST_ENTRY _EX_Flink; \
  116. PLIST_ENTRY _EX_ListHead; \
  117. _EX_ListHead = (ListHead); \
  118. _EX_Flink = _EX_ListHead->Flink; \
  119. (Entry)->Flink = _EX_Flink; \
  120. (Entry)->Blink = _EX_ListHead; \
  121. _EX_Flink->Blink = (Entry); \
  122. _EX_ListHead->Flink = (Entry); \
  123. }
  124. //
  125. // VOID
  126. // InsertSortedList(
  127. // PLIST_ENTRY ListHead,
  128. // PLIST_ENTRY Entry,
  129. // LONG(*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
  130. // );
  131. //
  132. #define InsertSortedList(ListHead, Entry, CompareFunction) \
  133. { \
  134. PLIST_ENTRY _EX_Entry; \
  135. PLIST_ENTRY _EX_Blink; \
  136. for (_EX_Entry = (ListHead)->Flink; \
  137. _EX_Entry != (ListHead); \
  138. _EX_Entry = _EX_Entry->Flink) \
  139. if ((*(CompareFunction))((Entry), _EX_Entry) <= 0) \
  140. break; \
  141. _EX_Blink = _EX_Entry->Blink; \
  142. _EX_Blink->Flink = (Entry); \
  143. _EX_Entry->Blink = (Entry); \
  144. (Entry)->Flink = _EX_Entry; \
  145. (Entry)->Blink = _EX_Blink; \
  146. }
  147. //
  148. // Finds an 'Entry' equal to 'Key' in a 'List'
  149. //
  150. // VOID
  151. // FindList(
  152. // PLIST_ENTRY ListHead,
  153. // PLIST_ENTRY Key,
  154. // PLIST_ENTRY *Entry,
  155. // LONG (*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
  156. // );
  157. //
  158. #define FindList(ListHead, Key, Entry, CompareFunction) \
  159. { \
  160. PLIST_ENTRY _EX_Entry; \
  161. *(Entry) = NULL; \
  162. for (_EX_Entry = (ListHead)->Flink; \
  163. _EX_Entry != (ListHead); \
  164. _EX_Entry = _EX_Entry->Flink) \
  165. if ((*(CompareFunction))((Key), _EX_Entry) is 0) \
  166. { \
  167. *(Entry) = _EX_Entry; \
  168. break; \
  169. } \
  170. }
  171. //
  172. // Finds an 'Entry' equal to or greater than 'Key' in a sorted 'List'
  173. //
  174. // VOID
  175. // FindSortedList(
  176. // PLIST_ENTRY ListHead,
  177. // PLIST_ENTRY Key,
  178. // PLIST_ENTRY *Entry,
  179. // LONG (*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
  180. // );
  181. //
  182. #define FindSortedList(ListHead, Key, Entry, CompareFunction) \
  183. { \
  184. PLIST_ENTRY _EX_Entry; \
  185. *(Entry) = NULL; \
  186. for (_EX_Entry = (ListHead)->Flink; \
  187. _EX_Entry != (ListHead); \
  188. _EX_Entry = _EX_Entry->Flink) \
  189. if ((*(CompareFunction))((Key), _EX_Entry) <= 0) \
  190. { \
  191. *(Entry) = _EX_Entry; \
  192. break; \
  193. } \
  194. }
  195. //
  196. // Applies a 'Function' to all entries in a list.
  197. //
  198. // VOID
  199. // MapCarList(
  200. // PLIST_ENTRY ListHead,
  201. // VOID(*VoidFunction)(PLIST_ENTRY)
  202. // );
  203. //
  204. #define MapCarList(ListHead, VoidFunction) \
  205. { \
  206. PLIST_ENTRY _EX_Entry; \
  207. for (_EX_Entry = (ListHead)->Flink; \
  208. _EX_Entry != (ListHead); \
  209. _EX_Entry = _EX_Entry->Flink) \
  210. (*(VoidFunction))(_EX_Entry); \
  211. }
  212. //
  213. // Frees a list.
  214. //
  215. // VOID
  216. // FreeList(
  217. // PLIST_ENTRY ListHead,
  218. // VOID(*FreeFunction)(PLIST_ENTRY)
  219. // );
  220. //
  221. #define FreeList(ListHead, FreeFunction) \
  222. { \
  223. PLIST_ENTRY _EX_Head; \
  224. while (!IsListEmpty(ListHead)) \
  225. { \
  226. _EX_Head = RemoveHeadList(ListHead); \
  227. (*(FreeFunction))(_EX_Head); \
  228. } \
  229. }
  230. #define QUEUE_ENTRY LIST_ENTRY
  231. #define PQUEUE_ENTRY PLIST_ENTRY
  232. //
  233. // VOID
  234. // InitializeQueueHead(
  235. // PQUEUE_ENTRY QueueHead
  236. // );
  237. //
  238. #define InitializeQueueHead(QueueHead) InitializeListHead(QueueHead)
  239. //
  240. // BOOLEAN
  241. // IsQueueEmpty(
  242. // PQUEUE_ENTRY QueueHead
  243. // );
  244. //
  245. #define IsQueueEmpty(QueueHead) IsListEmpty(QueueHead)
  246. //
  247. // VOID
  248. // Enqueue(
  249. // PQUEUE_ENTRY QueueHead,
  250. // PQUEUE_ENTRY Entry
  251. // );
  252. //
  253. #define Enqueue(QueueHead, Entry) InsertTailList(QueueHead, Entry)
  254. //
  255. // PQUEUE_ENTRY
  256. // Dequeue(
  257. // PQUEUE_ENTRY QueueHead,
  258. // );
  259. //
  260. #define Dequeue(QueueHead) RemoveHeadList(QueueHead)
  261. //
  262. // VOID
  263. // FreeQueue(
  264. // PQUEUE_ENTRY QueueHead,
  265. // VOID(*FreeFunction)(PQUEUE_ENTRY)
  266. // );
  267. //
  268. #define FreeQueue(QueueHead, FreeFunction) \
  269. FreeList(QueueHead, FreeFunction)
  270. //
  271. // VOID
  272. // MapCarQueue(
  273. // PQUEUE_ENTRY QueueHead,
  274. // VOID(*VoidFunction)(PQUEUE_ENTRY)
  275. // );
  276. //
  277. #define MapCarQueue(QueueHead, VoidFunction) \
  278. MapCarList(QueueHead, VoidFunction)
  279. #define STACK_ENTRY LIST_ENTRY
  280. #define PSTACK_ENTRY PLIST_ENTRY
  281. //
  282. // VOID
  283. // InitializeStackHead(
  284. // PSTACK_ENTRY StackHead
  285. // );
  286. //
  287. #define InitializeStackHead(StackHead) InitializeListHead(StackHead)
  288. //
  289. // BOOLEAN
  290. // IsStackEmpty(
  291. // PSTACK_ENTRY StackHead
  292. // );
  293. //
  294. #define IsStackEmpty(StackHead) IsListEmpty(StackHead)
  295. //
  296. // VOID
  297. // Push(
  298. // PSTACK_ENTRY StackHead,
  299. // PSTACK_ENTRY Entry
  300. // );
  301. //
  302. #define Push(StackHead, Entry) InsertHeadList(StackHead, Entry)
  303. //
  304. // PSTACK_ENTRY
  305. // Pop(
  306. // PSTACK_ENTRY StackHead,
  307. // );
  308. //
  309. #define Pop(StackHead) RemoveHeadList(StackHead)
  310. //
  311. // VOID
  312. // FreeStack(
  313. // PSTACK_ENTRY StackHead,
  314. // VOID(*FreeFunction)(PSTACK_ENTRY)
  315. // );
  316. //
  317. #define FreeStack(StackHead, FreeFunction) \
  318. FreeList(StackHead, FreeFunction)
  319. //
  320. // VOID
  321. // MapCarStack(
  322. // PSTACK_ENTRY StackHead,
  323. // VOID(*VoidFunction)(PSTACK_ENTRY)
  324. // );
  325. //
  326. #define MapCarStack(StackHead, VoidFunction) \
  327. MapCarList(StackHead, VoidFunction)
  328. #endif // _LIST_H_