From 39b1c8afdf2713ca12123ef00f32d14a95dadab4 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Sun, 7 Jul 2013 21:37:38 +0200 Subject: Add intrusive list class. --- util/intrusive_list.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 util/intrusive_list.h (limited to 'util/intrusive_list.h') diff --git a/util/intrusive_list.h b/util/intrusive_list.h new file mode 100644 index 0000000..1a02902 --- /dev/null +++ b/util/intrusive_list.h @@ -0,0 +1,104 @@ +#ifndef INTRUSIVE_LIST_H +#define INTRUSIVE_LIST_H + +// TODO: Make this noncopyable. +template +class ListHandle { + private: + ListHandle* prev; + ListHandle* next; + + void insert_between(ListHandle& new_prev, ListHandle& new_next) { + if(new_prev.p == p || new_next.p == p) { + return; + } + + // Remove this element from any previous position first. + prev->next = next; + next->prev = prev; + + // Insert this element into new position. + prev = &new_prev; + next = &new_next; + prev->next = this; + next->prev = this; + } + + public: + T* const p; + + ListHandle(T* ptr) : prev(this), next(this), p(ptr) {} + + ListHandle* get_prev() { + return prev; + } + + ListHandle* get_next() { + return next; + } + + void insert_before(ListHandle& node) { + insert_between(*node.prev, node); + } + + void insert_after(ListHandle& node) { + insert_between(node, *node.next); + } +}; + +template +class List { + private: + ListHandle root; + + public: + class Iterator { + private: + ListHandle* h; + + public: + Iterator(ListHandle* handle) : h(handle) {} + + ListHandle* operator*() { + return h; + } + + ListHandle* operator->() { + return h; + } + + bool operator==(const Iterator& i) { + return h == i.h; + } + + bool operator!=(const Iterator& i) { + return h != i.h; + } + + Iterator& operator++() { + h = h->get_next(); + return *this; + } + }; + + List() : root(nullptr) {} + + Iterator begin() { + return {root.get_next()}; + } + + Iterator end() { + return {&root}; + } + + bool empty() { + return begin() == end(); + } + + void append(ListHandle& handle) { + //root.insert_before(&handle); + handle.insert_before(root); + } +}; + +#endif -- cgit v1.2.3