xref: /haiku/headers/private/kernel/util/list.h (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 /*
2  * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef KERNEL_LIST_H
6 #define KERNEL_LIST_H
7 
8 
9 #include <SupportDefs.h>
10 
11 
12 /* This header defines a doubly-linked list. It differentiates between a link
13  * and an item.
14  * A link is what is put into and removed from a list, an item is the whole
15  * object that contains the link. The item doesn't have to be begin with a
16  * link; the offset to the link structure is given to init_list_etc(), so that
17  * list_get_next/prev_item() will work correctly.
18  * Note, the offset value is only needed for the *_item() functions. If the
19  * offset is 0, list_link and item are identical - if you use init_list(),
20  * you don't have to care about the difference between a link and an item.
21  */
22 
23 
24 // The use of offsetof() on non-PODs is invalid. Since many structs use
25 // templated members (i.e. DoublyLinkedList) which makes them non-PODs we
26 // can't use offsetof() anymore. This macro does the same, but requires an
27 // instance of the object in question.
28 #define offset_of_member(OBJECT, MEMBER) \
29 	((size_t)((char*)&OBJECT.MEMBER - (char*)&OBJECT))
30 
31 
32 typedef struct list_link list_link;
33 
34 /* The object that is put into the list must begin with these
35  * fields, but it doesn't have to be this structure.
36  */
37 
38 struct list_link {
39 	list_link	*next;
40 	list_link	*prev;
41 };
42 
43 struct list {
44 	list_link	link;
45 	int32		offset;
46 };
47 
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 extern void list_init(struct list *list);
54 extern void list_init_etc(struct list *list, int32 offset);
55 extern void list_add_link_to_head(struct list *list, void *_link);
56 extern void list_add_link_to_tail(struct list *list, void *_link);
57 extern void list_remove_link(void *_link);
58 extern void *list_get_next_item(struct list *list, void *item);
59 extern void *list_get_prev_item(struct list *list, void *item);
60 extern void *list_get_last_item(struct list *list);
61 extern void list_add_item(struct list *list, void *item);
62 extern void list_remove_item(struct list *list, void *item);
63 extern void list_insert_item_before(struct list *list, void *before, void *item);
64 extern void *list_remove_head_item(struct list *list);
65 extern void *list_remove_tail_item(struct list *list);
66 extern void list_move_to_list(struct list *sourceList, struct list *targetList);
67 
68 static inline bool
69 list_is_empty(struct list *list)
70 {
71 	return list->link.next == (list_link *)list;
72 }
73 
74 static inline void *
75 list_get_first_item(struct list *list)
76 {
77 	return list_get_next_item(list, NULL);
78 }
79 
80 #ifdef __cplusplus
81 }
82 #endif
83 
84 #endif	/* KERNEL_LIST_H */
85