Skip to content

Instantly share code, notes, and snippets.

@vfreex
Created November 17, 2016 10:49
Show Gist options
  • Save vfreex/7135cc64f87c75e67de8eb03fae9729e to your computer and use it in GitHub Desktop.
Save vfreex/7135cc64f87c75e67de8eb03fae9729e to your computer and use it in GitHub Desktop.
simple doubly linked list that is similar to the linux kernel
#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