list.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
  3. (c) Copyright 2000-2004 Convergence (integrated media) GmbH
  4. All rights reserved.
  5. Written by Denis Oliver Kropp <dok@directfb.org>,
  6. Andreas Hundt <andi@fischlustig.de>,
  7. Sven Neumann <neo@directfb.org>,
  8. Ville Syrjälä <syrjala@sci.fi> and
  9. Claudio Ciccani <klan@users.sf.net>.
  10. This library is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU Lesser General Public
  12. License as published by the Free Software Foundation; either
  13. version 2 of the License, or (at your option) any later version.
  14. This library is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. Lesser General Public License for more details.
  18. You should have received a copy of the GNU Lesser General Public
  19. License along with this library; if not, write to the
  20. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. Boston, MA 02111-1307, USA.
  22. */
  23. #ifndef __DIRECT__LIST_H__
  24. #define __DIRECT__LIST_H__
  25. #include <direct/types.h>
  26. #include <direct/debug.h>
  27. struct __D_DirectLink {
  28. int magic;
  29. DirectLink *next;
  30. DirectLink *prev; /* The 'prev' pointer of the first element always points
  31. to the last element of the list, for fast appending ;-) */
  32. };
  33. static __inline__ void
  34. direct_list_prepend( DirectLink **list, DirectLink *link )
  35. {
  36. DirectLink *first = *list;
  37. link->next = first;
  38. if (first) {
  39. D_MAGIC_ASSERT( first, DirectLink );
  40. link->prev = first->prev;
  41. first->prev = link;
  42. }
  43. else
  44. link->prev = link;
  45. *list = link;
  46. D_MAGIC_SET( link, DirectLink );
  47. }
  48. static __inline__ void
  49. direct_list_append( DirectLink **list, DirectLink *link )
  50. {
  51. DirectLink *first = *list;
  52. link->next = NULL;
  53. if (first) {
  54. DirectLink *last = first->prev;
  55. D_MAGIC_ASSERT( first, DirectLink );
  56. D_MAGIC_ASSERT( last, DirectLink );
  57. link->prev = last;
  58. last->next = first->prev = link;
  59. }
  60. else
  61. *list = link->prev = link;
  62. D_MAGIC_SET( link, DirectLink );
  63. }
  64. static __inline__ bool
  65. direct_list_contains_element_EXPENSIVE( DirectLink *list, DirectLink *link )
  66. {
  67. D_MAGIC_ASSERT_IF( list, DirectLink );
  68. while (list) {
  69. if (list == link)
  70. return true;
  71. list = list->next;
  72. }
  73. return false;
  74. }
  75. static __inline__ int
  76. direct_list_count_elements_EXPENSIVE( DirectLink *list )
  77. {
  78. int count = 0;
  79. while (list) {
  80. D_MAGIC_ASSERT( list, DirectLink );
  81. count++;
  82. list = list->next;
  83. }
  84. return count;
  85. }
  86. static __inline__ void
  87. direct_list_remove( DirectLink **list, DirectLink *link )
  88. {
  89. DirectLink *next;
  90. DirectLink *prev;
  91. D_ASSERT( list != NULL );
  92. D_ASSERT( direct_list_contains_element_EXPENSIVE( *list, link ) );
  93. D_MAGIC_ASSERT( *list, DirectLink );
  94. D_MAGIC_ASSERT( link, DirectLink );
  95. next = link->next;
  96. prev = link->prev;
  97. if (next) {
  98. D_MAGIC_ASSERT( next, DirectLink );
  99. next->prev = prev;
  100. }
  101. else
  102. (*list)->prev = prev;
  103. if (link == *list)
  104. *list = next;
  105. else {
  106. D_MAGIC_ASSERT( prev, DirectLink );
  107. prev->next = next;
  108. }
  109. link->next = link->prev = NULL;
  110. D_MAGIC_CLEAR( link );
  111. }
  112. static __inline__ void
  113. direct_list_move_to_front( DirectLink **list, DirectLink *link )
  114. {
  115. DirectLink *next;
  116. DirectLink *prev;
  117. DirectLink *first;
  118. D_ASSERT( list != NULL );
  119. first = *list;
  120. D_ASSERT( direct_list_contains_element_EXPENSIVE( first, link ) );
  121. D_MAGIC_ASSERT( first, DirectLink );
  122. D_MAGIC_ASSERT( link, DirectLink );
  123. if (first == link)
  124. return;
  125. next = link->next;
  126. prev = link->prev;
  127. D_MAGIC_ASSERT_IF( next, DirectLink );
  128. D_MAGIC_ASSERT( prev, DirectLink );
  129. if (next) {
  130. next->prev = prev;
  131. link->prev = first->prev;
  132. }
  133. else
  134. link->prev = prev;
  135. prev->next = next;
  136. link->next = first;
  137. first->prev = link;
  138. *list = link;
  139. }
  140. #define direct_list_check_link( link ) \
  141. ({ \
  142. D_MAGIC_ASSERT_IF( link, DirectLink ); \
  143. link != NULL; \
  144. })
  145. #define direct_list_foreach(elem, list) \
  146. for (elem = (__typeof__(elem))(list); \
  147. direct_list_check_link( (DirectLink*)(elem) ); \
  148. elem = (__typeof__(elem))(((DirectLink*)(elem))->next))
  149. #define direct_list_foreach_reverse(elem, list) \
  150. for (elem = (__typeof__(elem))((list) ? (list)->prev : NULL); \
  151. direct_list_check_link( (DirectLink*)(elem) ); \
  152. elem = (__typeof__(elem))((((DirectLink*)(elem))->prev->next) ? ((DirectLink*)(elem))->prev : NULL))
  153. #define direct_list_foreach_safe(elem, temp, list) \
  154. for (elem = (__typeof__(elem))(list), temp = ((__typeof__(temp))(elem) ? (__typeof__(temp))(((DirectLink*)(elem))->next) : NULL); \
  155. direct_list_check_link( (DirectLink*)(elem) ); \
  156. elem = (__typeof__(elem))(temp), temp = ((__typeof__(temp))(elem) ? (__typeof__(temp))(((DirectLink*)(elem))->next) : NULL))
  157. #endif