FreeTDS API
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dlist.tmpl.h
1 /* Dlist - dynamic list
2  * Copyright (C) 2016 Frediano Ziglio
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  */
19 
20 #if !defined(DLIST_FUNC) || !defined(DLIST_TYPE) || !defined(DLIST_LIST_TYPE)
21 #error Required defines missing!
22 #endif
23 
24 typedef struct
25 {
26  DLIST_FIELDS(DLIST_TYPE);
28 
29 #define DLIST_FAKE(list) ((DLIST_TYPE *) (((char *) (list)) - TDS_OFFSET(DLIST_TYPE, next)))
30 
31 static inline void DLIST_FUNC(init)(DLIST_LIST_TYPE *list)
32 {
33  list->next = list->prev = DLIST_FAKE(list);
34 }
35 
36 static inline void DLIST_FUNC(check)(DLIST_LIST_TYPE *list)
37 {
38 #if ENABLE_EXTRA_CHECKS
39  DLIST_TYPE *item = list->next;
40  DLIST_TYPE *end = DLIST_FAKE(list);
41  assert(item != NULL);
42  do {
43  assert(item->prev->next == item);
44  assert(item->next->prev == item);
45  item = item->next;
46  } while (item != end);
47 #endif
48 }
49 
50 static inline DLIST_TYPE *DLIST_FUNC(first)(DLIST_LIST_TYPE *list)
51 {
52  return list->next == DLIST_FAKE(list) ? NULL : list->next;
53 }
54 
55 static inline DLIST_TYPE *DLIST_FUNC(last)(DLIST_LIST_TYPE *list)
56 {
57  return list->prev == DLIST_FAKE(list) ? NULL : list->prev;
58 }
59 
60 static inline DLIST_TYPE *DLIST_FUNC(next)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
61 {
62  return item->next == DLIST_FAKE(list) ? NULL : item->next;
63 }
64 
65 static inline DLIST_TYPE *DLIST_FUNC(prev)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
66 {
67  return item->prev == DLIST_FAKE(list) ? NULL : item->prev;
68 }
69 
70 static inline void DLIST_FUNC(prepend)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
71 {
72  DLIST_FUNC(check)(list);
73  assert(item->next == NULL && item->prev == NULL);
74  list->next->prev = item;
75  item->next = list->next;
76  item->prev = DLIST_FAKE(list);
77  list->next = item;
78  assert(item->next != NULL && item->prev != NULL);
79  DLIST_FUNC(check)(list);
80 }
81 
82 static inline void DLIST_FUNC(append)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
83 {
84  DLIST_FUNC(check)(list);
85  assert(item->next == NULL && item->prev == NULL);
86  list->prev->next = item;
87  item->prev = list->prev;
88  item->next = DLIST_FAKE(list);
89  list->prev = item;
90  assert(item->next != NULL && item->prev != NULL);
91  DLIST_FUNC(check)(list);
92 }
93 
94 static inline void DLIST_FUNC(remove)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
95 {
96  DLIST_TYPE *prev = item->prev, *next = item->next;
97  DLIST_FUNC(check)(list);
98  if (prev)
99  prev->next = next;
100  if (next)
101  next->prev = prev;
102  item->prev = NULL;
103  item->next = NULL;
104  DLIST_FUNC(check)(list);
105 }
106 
107 static inline bool DLIST_FUNC(in_list)(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
108 {
109  DLIST_FUNC(check)(list);
110  return item->prev != NULL || item->next != NULL;
111 }
112 
113 #undef DLIST_FAKE
114 #undef DLIST_NAME
115 #undef DLIST_TYPE
116 #undef DLIST_LIST_TYPE
117 
Definition: dlist.tmpl.h:24