lists.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* lists.h: Definitions for linked lists
  2. Copyright (C) 2002-2003 Sebastian Reichelt
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #ifndef LISTS_H
  15. #define LISTS_H
  16. #define LIST_HEADER(Type) struct { Type *First, *Last; } Header
  17. #define LIST_ITEM_HEADER(Type) struct { Type *Prev, *Next; } Header
  18. #define GetPrev(Item) ((Item)->Header.Prev)
  19. #define GetNext(Item) ((Item)->Header.Next)
  20. #define GetFirst(List) ((List).Header.First)
  21. #define GetLast(List) ((List).Header.Last)
  22. #define IsEmpty(List) (!(GetFirst (List)))
  23. #define Unlink(List,Item) ({ \
  24. if ((Item) == GetFirst (List)) \
  25. (List).Header.First = GetNext (Item); \
  26. if ((Item) == GetLast (List)) \
  27. (List).Header.Last = GetPrev (Item); \
  28. if (GetPrev (Item)) \
  29. GetPrev(Item)->Header.Next = GetNext (Item); \
  30. if (GetNext (Item)) \
  31. GetNext(Item)->Header.Prev = GetPrev (Item); \
  32. (Item)->Header.Prev = NULL; \
  33. (Item)->Header.Next = NULL; \
  34. })
  35. #define Append(List,Item) ({ \
  36. (Item)->Header.Prev = GetLast (List); \
  37. (Item)->Header.Next = NULL; \
  38. if (!(GetFirst (List))) \
  39. (List).Header.First = (Item); \
  40. if (GetLast (List)) \
  41. GetLast(List)->Header.Next = (Item); \
  42. (List).Header.Last = (Item); \
  43. })
  44. #define Push(List,Item) ({ \
  45. (Item)->Header.Prev = NULL; \
  46. (Item)->Header.Next = GetFirst (List); \
  47. if (GetFirst (List)) \
  48. GetFirst(List)->Header.Prev = (Item); \
  49. (List).Header.First = (Item); \
  50. if (!(GetLast (List))) \
  51. (List).Header.Last = (Item); \
  52. })
  53. #define InsertAfter(List,Item,After) ({ \
  54. if (!(After)) \
  55. Push (List, Item); \
  56. else \
  57. { \
  58. (Item)->Header.Next = GetNext (After); \
  59. (Item)->Header.Prev = (After); \
  60. (After)->Header.Next = (Item); \
  61. if (GetNext (Item)) \
  62. GetNext(Item)->Header.Prev = (Item); \
  63. else \
  64. (List).Header.Last = (Item); \
  65. } \
  66. })
  67. #define InsertBefore(List,Item,Before) ({ \
  68. if (!(Before)) \
  69. Append (List, Item); \
  70. else \
  71. InsertAfter (List, Item, GetPrev (Before)); \
  72. })
  73. #define for_each(Item,List) for ((Item) = GetFirst (List); (Item); (Item) = GetNext (Item))
  74. #define CountItems(List,Type) ({ \
  75. unsigned long Result = 0; \
  76. Type *Item; \
  77. for_each (Item, List) \
  78. Result++; \
  79. Result; \
  80. })
  81. #endif