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 */