From 8174112d403e07fddc72d574aa02b2412700f5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 13 Oct 2003 01:57:05 +0000 Subject: [PATCH] Almost straight copy of the list.h doubly linked list implementation to a C++ one ready for kernel use, but very basic, too. Has not been tested yet, expect some bug fixes soon. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5001 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/kernel/util/DoublyLinkedList.h | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 headers/private/kernel/util/DoublyLinkedList.h diff --git a/headers/private/kernel/util/DoublyLinkedList.h b/headers/private/kernel/util/DoublyLinkedList.h new file mode 100644 index 0000000000..2a3a6b79cb --- /dev/null +++ b/headers/private/kernel/util/DoublyLinkedList.h @@ -0,0 +1,126 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef KERNEL_UTIL_DOUBLY_LINKED_LIST_H +#define KERNEL_UTIL_DOUBLY_LINKED_LIST_H + + +#include + + +#ifdef __cplusplus + +/* This header defines a doubly-linked list. It differentiates between a link + * and an item. + * It's the C++ version of it's very small and efficient, but + * has not been perfectly C++-ified yet. + * The link must be part of the item, it cannot be allocated on demand yet. + */ + +namespace DoublyLinked { + +class Link { + public: + Link *next; + Link *prev; +}; + +template class Iterator; + +template +class List { + public: + //typedef typename Item ValueType; + typedef Iterator IteratorType; + + List() + { + fLink.next = fLink.prev = &fLink; + } + + void Add(Item *item) + { + //Link *link = &item->*LinkMember; + (item->*LinkMember).next = &fLink; + (item->*LinkMember).prev = fLink.prev; + + fLink.prev->next = &(item->*LinkMember); + fLink.prev = &(item->*LinkMember); + } + + void Remove(Item *item) + { + (item->*LinkMember).next->prev = (item->*LinkMember).prev; + (item->*LinkMember).prev->next = (item->*LinkMember).next; + } + + Item *RemoveHead() + { + if (IsEmpty()) + return NULL; + + Item *item = GetItem(fLink.next); + Remove(item); + + return item; + } + + IteratorType Iterator() + { + return IteratorType(*this); + } + + bool IsEmpty() + { + return fLink.next == &fLink; + } + + Link *Head() + { + return fLink.next; + } + + + static inline size_t Offset() + { + return (size_t)&(((Item *)1)->*LinkMember) - 1; + } + + static inline Item *GetItem(Link *link) + { + return (Item *)((uint8 *)link - Offset()); + } + + private: + Link fLink; +}; + +template +class Iterator { + public: + typedef List ListType; + + Iterator() : fCurrent(NULL) {} + Iterator(ListType &list) : fCurrent(list.Head()) {} + + Item *Next() + { + if (fCurrent->next == NULL) + return NULL; + + Link *current = fCurrent; + fCurrent = fCurrent->next; + + return ListType::GetItem(current); + } + + private: + Link *fCurrent; +}; + +} // namespace DoublyLinked + +#endif /* __cplusplus */ + +#endif /* KERNEL_UTIL_DOUBLY_LINKED_LIST_H */