Skip to content

Instantly share code, notes, and snippets.

@jstaursky
Created September 14, 2022 13:00
Show Gist options
  • Save jstaursky/7943776797ef3a6a5d72cddba580aa3a to your computer and use it in GitHub Desktop.
Save jstaursky/7943776797ef3a6a5d72cddba580aa3a to your computer and use it in GitHub Desktop.
intrusive linked list example
#include <iostream>
#include <cstring>
#include <string>
struct list_head {
struct list_head *next, *prev;
};
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
#ifndef container_of
#define container_of(ptr, type, member) __extension__ ({ \
const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
#define list_entry(ptr, type, member) container_of(ptr, type, member)
void __list_add(struct list_head * add,
struct list_head * prev,
struct list_head * next)
{
next->prev = add;
add->next = next;
add->prev = prev;
prev->next = add;
}
void list_add_tail(struct list_head *add, struct list_head *head)
{
__list_add(add, head->prev, head);
}
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
struct PhoneBook {
struct list_head people_head;
int npages;
};
struct Person {
struct list_head people_list;
char *name;
};
int main(int argc, char *argv[])
{
list_head *p = (list_head*)0;
PhoneBook *book = new PhoneBook();
book->npages = 300;
INIT_LIST_HEAD(&book->people_head);
Person *person = new Person();
INIT_LIST_HEAD(&person->people_list);
person->name = new char[80];
memcpy(person->name, "John Doe", sizeof("John Doe"));
list_add_tail(&person->people_list, &book->people_head);
Person *somebody;
list_for_each(p, &book->people_head) {
somebody = list_entry(p, Person, people_list);
std::cout << somebody->name << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment