Files
haiku-beta6/headers/private/kernel/util/SinglyLinkedList.h
T

260 lines
5.0 KiB
C++
Raw Normal View History

/*
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2005-2006, Ingo Weinhold, [email protected]. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_UTIL_SINGLY_LINKED_LIST_H
#define KERNEL_UTIL_SINGLY_LINKED_LIST_H
2003-06-23 05:54:53 +00:00
#ifdef __cplusplus
2003-06-23 05:54:53 +00:00
// SinglyLinkedListLink
template<typename Element>
class SinglyLinkedListLink {
2003-06-23 05:54:53 +00:00
public:
SinglyLinkedListLink() : next(NULL) {}
~SinglyLinkedListLink() {}
Element *next;
2003-06-23 05:54:53 +00:00
};
// SinglyLinkedListLinkImpl
template<typename Element>
class SinglyLinkedListLinkImpl {
private:
typedef SinglyLinkedListLink<Element> SLL_Link;
2003-06-23 05:54:53 +00:00
public:
SinglyLinkedListLinkImpl() : fSinglyLinkedListLink() {}
~SinglyLinkedListLinkImpl() {}
SLL_Link* GetSinglyLinkedListLink()
{ return &fSinglyLinkedListLink; }
const SLL_Link* GetSinglyLinkedListLink() const
{ return &fSinglyLinkedListLink; }
2003-06-23 05:54:53 +00:00
private:
SLL_Link fSinglyLinkedListLink;
2003-06-23 05:54:53 +00:00
};
// SinglyLinkedListStandardGetLink
template<typename Element>
class SinglyLinkedListStandardGetLink {
private:
typedef SinglyLinkedListLink<Element> Link;
2003-06-23 05:54:53 +00:00
public:
inline Link* operator()(Element* element) const
{
return element->GetSinglyLinkedListLink();
}
inline const Link* operator()(const Element* element) const
{
return element->GetSinglyLinkedListLink();
}
};
2003-06-23 05:54:53 +00:00
// SinglyLinkedListMemberGetLink
template<typename Element,
SinglyLinkedListLink<Element> Element::* LinkMember = &Element::fLink>
class SinglyLinkedListMemberGetLink {
private:
typedef SinglyLinkedListLink<Element> Link;
2003-06-23 05:54:53 +00:00
public:
inline Link* operator()(Element* element) const
{
return &(element->*LinkMember);
}
inline const Link* operator()(const Element* element) const
{
return &(element->*LinkMember);
2003-06-23 05:54:53 +00:00
}
};
2003-06-23 05:54:53 +00:00
// for convenience
#define SINGLY_LINKED_LIST_TEMPLATE_LIST \
template<typename Element, typename GetLink>
#define SINGLY_LINKED_LIST_CLASS_NAME SinglyLinkedList<Element, GetLink>
2003-06-23 05:54:53 +00:00
template<typename Element,
typename GetLink = SinglyLinkedListStandardGetLink<Element> >
class SinglyLinkedList {
private:
typedef SinglyLinkedList<Element, GetLink> List;
typedef SinglyLinkedListLink<Element> Link;
2003-06-23 05:54:53 +00:00
public:
class Iterator {
public:
Iterator(const List* list)
:
fList(list)
{
Rewind();
}
2003-06-23 05:54:53 +00:00
Iterator(const Iterator& other)
{
*this = other;
}
2003-06-23 05:54:53 +00:00
bool HasNext() const
{
return fNext;
}
Element* Next()
{
Element* element = fNext;
if (fNext)
fNext = fList->GetNext(fNext);
return element;
}
Iterator& operator=(const Iterator& other)
{
fList = other.fList;
fNext = other.fNext;
return* this;
}
void Rewind()
{
fNext = fList->First();
}
private:
const List* fList;
Element* fNext;
};
public:
SinglyLinkedList() : fFirst(NULL) {}
~SinglyLinkedList() {}
inline bool IsEmpty() const { return (fFirst == NULL); }
2003-06-23 05:54:53 +00:00
inline void Add(Element* element);
inline void Remove(Element* element);
inline void RemoveAll();
inline void MakeEmpty() { RemoveAll(); }
inline Element* First() const { return fFirst; }
inline Element* Head() const { return fFirst; }
inline Element* RemoveHead();
inline Element* GetNext(Element* element) const;
inline int32 Size() const;
// O(n)!
inline Iterator GetIterator() const { return Iterator(this); }
private:
Element *fFirst;
static GetLink sGetLink;
};
// inline methods
// Add
SINGLY_LINKED_LIST_TEMPLATE_LIST
2003-06-23 05:54:53 +00:00
void
SINGLY_LINKED_LIST_CLASS_NAME::Add(Element* element)
2003-06-23 05:54:53 +00:00
{
if (element != NULL) {
Link* link = sGetLink(element);
link->next = fFirst;
fFirst = element;
}
2003-06-23 05:54:53 +00:00
}
// Remove
SINGLY_LINKED_LIST_TEMPLATE_LIST
void
SINGLY_LINKED_LIST_CLASS_NAME::Remove(Element* element)
2003-06-23 05:54:53 +00:00
{
if (element == NULL)
return;
Element* next = fFirst;
Element* last = NULL;
while (next != NULL && element != next) {
last = next;
next = sGetLink(next)->next;
}
2003-06-23 05:54:53 +00:00
Link* elementLink = sGetLink(element);
if (last == NULL)
fFirst = elementLink->next;
else
sGetLink(last)->next = elementLink->next;
2003-06-23 05:54:53 +00:00
elementLink->next = NULL;
2003-06-23 05:54:53 +00:00
}
// RemoveAll
SINGLY_LINKED_LIST_TEMPLATE_LIST
void
SINGLY_LINKED_LIST_CLASS_NAME::RemoveAll()
2003-06-23 05:54:53 +00:00
{
Element* element = fFirst;
while (element) {
Link* elLink = sGetLink(element);
element = elLink->next;
elLink->next = NULL;
}
fFirst = NULL;
2003-06-23 05:54:53 +00:00
}
// RemoveHead
SINGLY_LINKED_LIST_TEMPLATE_LIST
Element*
SINGLY_LINKED_LIST_CLASS_NAME::RemoveHead()
2003-06-23 05:54:53 +00:00
{
Element* element = Head();
Remove(element);
return element;
2003-06-23 05:54:53 +00:00
}
// GetNext
SINGLY_LINKED_LIST_TEMPLATE_LIST
Element*
SINGLY_LINKED_LIST_CLASS_NAME::GetNext(Element* element) const
2003-06-23 05:54:53 +00:00
{
Element* result = NULL;
if (element)
result = sGetLink(element)->next;
return result;
2003-06-23 05:54:53 +00:00
}
// Size
SINGLY_LINKED_LIST_TEMPLATE_LIST
int32
SINGLY_LINKED_LIST_CLASS_NAME::Size() const
2003-06-23 05:54:53 +00:00
{
int32 count = 0;
for (Element* element = First(); element; element = GetNext(element))
count++;
2003-06-23 05:54:53 +00:00
return count;
}
// sGetLink
SINGLY_LINKED_LIST_TEMPLATE_LIST
GetLink SINGLY_LINKED_LIST_CLASS_NAME::sGetLink;
2003-06-23 05:54:53 +00:00
#endif /* __cplusplus */
2003-06-23 05:54:53 +00:00
#endif // _KERNEL_UTIL_SINGLY_LINKED_LIST_H