diff options
| author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2013-07-07 21:37:38 +0200 | 
|---|---|---|
| committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2013-07-20 08:43:10 +0200 | 
| commit | 39b1c8afdf2713ca12123ef00f32d14a95dadab4 (patch) | |
| tree | 03f76edb9a5b0c1e6e7beff0452523fac13712e1 | |
| parent | 424136f1792dc0c0feb4ffcc15fc830aef2fd93e (diff) | |
Add intrusive list class.
| -rw-r--r-- | util/intrusive_list.h | 104 | 
1 files changed, 104 insertions, 0 deletions
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 <typename T> +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 <typename T> +class List { +	private: +		ListHandle<T> root; +	 +	public: +		class Iterator { +			private: +				ListHandle<T>* h; +			 +			public: +				Iterator(ListHandle<T>* handle) : h(handle) {} +				 +				ListHandle<T>* operator*() { +					return h; +				} +				 +				ListHandle<T>* 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<T>& handle) { +			//root.insert_before(&handle); +			handle.insert_before(root); +		} +}; + +#endif  | 
