Created
November 17, 2016 10:49
-
-
Save vfreex/7135cc64f87c75e67de8eb03fae9729e to your computer and use it in GitHub Desktop.
simple doubly linked list that is similar to the linux kernel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _LT_DOUBLY_LINKED_LIST_H | |
#define _LT_DOUBLY_LINKED_LIST_H | |
#ifndef offsetof | |
#define offsetof(type, member) \ | |
((size_t) &((type*) 0)->member) | |
#endif | |
#ifndef container_of | |
#define container_of(ptr, type, member) \ | |
((type*) ((char *)ptr - offsetof(type, member)) ) | |
#endif | |
#define LIST_POISON1 ((void *) 0x00100100) | |
#define LIST_POISON2 ((void *) 0x00200200) | |
struct lt_list_head { | |
struct lt_list_head *prev; | |
struct lt_list_head *next; | |
}; | |
#define LT_LIST_HEAD_INIT(head) \ | |
{ &(head), &(head) } | |
#define LT_LIST_HEAD(head) \ | |
struct lt_list_head head = LT_LIST_HEAD_INIT(head) | |
#define LT_INIT_LIST_HEAD(list) \ | |
do { (list)->next = (list)->prev = (list); } while(0) | |
static inline void __lt_list_add(struct lt_list_head *node, | |
struct lt_list_head *prev, | |
struct lt_list_head *next) | |
{ | |
node->next = next; | |
node->prev = prev; | |
prev->next = node; | |
next->prev = node; | |
} | |
static inline void lt_list_add(struct lt_list_head *node, struct lt_list_head *list) | |
{ | |
__lt_list_add(node, list, list->next); | |
} | |
static inline void lt_list_add_tail(struct lt_list_head *node, | |
struct lt_list_head *list) | |
{ | |
__lt_list_add(node, list->prev, list); | |
} | |
static inline void lt_list_unlink(struct lt_list_head *prev, | |
struct lt_list_head *next) | |
{ | |
prev->next = next; | |
next->prev = prev; | |
} | |
static inline void lt_list_del(struct lt_list_head *node) | |
{ | |
__lt_list_unlink(node->prev, node->next); | |
node->next = LIST_POISON1; | |
node->prev = LIST_POISON2; | |
} | |
static inline void lt_list_replace(struct lt_list_head *old, | |
struct lt_list_head *replacement) | |
{ | |
replacement->next = old->next; | |
replacement->prev = old->prev; | |
replacement->prev->next = replacement; | |
replacement->next->prev = replacement; | |
} | |
static inline void lt_list_del_init(struct lt_list_head *node) | |
{ | |
lt_list_unlink(node); | |
LT_INIT_LIST_HEAD(node); | |
} | |
static inline void lt_list_replace_init(struct lt_list_head *old, | |
struct lt_list_head *replacement) | |
{ | |
lt_list_replace(old, replacement); | |
LT_INIT_LIST_HEAD(old); | |
} | |
static inline void lt_list_move(struct lt_list_head *node, | |
struct lt_list_head *head) | |
{ | |
lt_list_unlink(node); | |
lt_list_add(node, head); | |
} | |
static inline void lt_list_move_tail(struct lt_list_head *node, | |
struct lt_list_head *head) | |
{ | |
lt_list_unlink(node); | |
lt_list_add_tail(node, head); | |
} | |
static inline lt_list_is_last(const struct lt_list_head *node, | |
const struct lt_list_head *head) | |
{ | |
return node == head->prev; | |
} | |
static inline lt_list_empty(const struct lt_list_head *head) | |
{ | |
return head->next == head; | |
} | |
static inline lt_list_empty_careful(const struct lt_list_head *head) | |
{ | |
return head == head->next && head = head->prev; | |
} | |
static inline void lt_list_rotate_left(struct lt_list_head *head) | |
{ | |
if (lt_list_empty(head)) | |
return; | |
lt_list_move_tail(head->next, head); | |
} | |
static inline int lt_list_is_singular(const struct list_head *head) | |
{ | |
return !lt_list_empty(head) && head->next == head->prev; | |
} | |
static inline void lt_list_cut_position(struct list_head *list, | |
struct list_head *head, struct list_head *entry) | |
{ | |
list->next = head->next; | |
head->next = entry->next; | |
entry->next = list; | |
list->prev = entry; | |
list->next->prev = list; | |
head->next->prev = head; | |
} | |
#define lt_list_entry(ptr, type, member) \ | |
container_of(ptr, type, member) | |
#define lt_list_first_entry(ptr, type, member) \ | |
container_of((ptr)->next, type, member) | |
#define lt_list_for_each(pos, head) \ | |
for (pos = (head)->next; pos != (head); pos = pos->next) | |
#define lt_list_for_each_prev(pos, head) \ | |
for (pos = (head)->prev; pos != (head); pos = pos->prev) | |
#define lt_list_for_each_safe(pos, n, head) \ | |
for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = n->next) | |
#define lt_list_for_each_prev_safe(pos, n, head) \ | |
for (pos = (head)->prev, n = pos->prev; pos != (head); pos = n, n = n->prev) | |
#define lt_list_for_each_entry(pos, head, member) \ | |
for (pos = lt_list_entry((head)->next, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_reverse(pos, head, member) \ | |
for (pos = lt_list_entry((head)->prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_prepare_entry(pos, head, member) \ | |
(pos ? pos : lt_list_entry(head, typeof(*pos), member)) | |
#define lt_list_for_each_entry_continue(pos, head, member) \ | |
for (pos = lt_list_entry(pos->member.next, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_continue_reverse(pos, head, member) \ | |
for (pos = lt_list_entry(pos->member.prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_for_each_entry_from(pos, head, member) \ | |
for (; &pos->member != (head); \ | |
pos = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_from_reverse(pos, head, member) \ | |
for (; &pos->member != (head); \ | |
pos = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe(pos, n, head, member) \ | |
for (pos = lt_list_entry((head)->next, typeof(*pos), member), \ | |
n = lt_list_entry(pos->member.next, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe_reverse(pos, n, head, member) \ | |
for (pos = lt_list_entry((head)->prev, typeof(*pos), member), \ | |
n = lt_list_entry(pos->member.prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe_continue(pos, n, head, member) \ | |
for (pos = lt_list_entry(pos->member.next, typeof(*pos), member), \ | |
n = lt_list_entry(pos->member.prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe_continue_reverse(pos, n, head, member) \ | |
for (pos = lt_list_entry(pos->member.prev, typeof(*pos), member), \ | |
n = lt_list_entry(pos->member.prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe_from(pos, n, head, member) \ | |
for (n = lt_list_entry(pos->member.next, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.next, typeof(*pos), member)) | |
#define lt_list_for_each_entry_safe_from_reverse(pos, head, member) \ | |
for (n = lt_list_entry(pos->member.prev, typeof(*pos), member); \ | |
&pos->member != (head); \ | |
pos = n, n = lt_list_entry(pos->member.prev, typeof(*pos), member)) | |
#define lt_list_safe_reset_next(pos, n, member) \ | |
n = lt_list_entry(pos->member.prev, typeof(*pos), member) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment