2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Copyright 2005-2006, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
5 * Distributed under the terms of the MIT License.
7 #ifndef KERNEL_UTIL_SINGLY_LINKED_LIST_H
8 #define KERNEL_UTIL_SINGLY_LINKED_LIST_H
11 #include "fssh_types.h"
19 // SinglyLinkedListLink
20 template<typename Element
>
21 class SinglyLinkedListLink
{
23 SinglyLinkedListLink() : next(NULL
) {}
24 ~SinglyLinkedListLink() {}
29 // SinglyLinkedListLinkImpl
30 template<typename Element
>
31 class SinglyLinkedListLinkImpl
{
33 typedef SinglyLinkedListLink
<Element
> SLL_Link
;
36 SinglyLinkedListLinkImpl() : fSinglyLinkedListLink() {}
37 ~SinglyLinkedListLinkImpl() {}
39 SLL_Link
* GetSinglyLinkedListLink()
40 { return &fSinglyLinkedListLink
; }
41 const SLL_Link
* GetSinglyLinkedListLink() const
42 { return &fSinglyLinkedListLink
; }
45 SLL_Link fSinglyLinkedListLink
;
48 // SinglyLinkedListStandardGetLink
49 template<typename Element
>
50 class SinglyLinkedListStandardGetLink
{
52 typedef SinglyLinkedListLink
<Element
> Link
;
55 inline Link
* operator()(Element
* element
) const
57 return element
->GetSinglyLinkedListLink();
60 inline const Link
* operator()(const Element
* element
) const
62 return element
->GetSinglyLinkedListLink();
66 // SinglyLinkedListMemberGetLink
67 template<typename Element
,
68 SinglyLinkedListLink
<Element
> Element::* LinkMember
= &Element::fLink
>
69 class SinglyLinkedListMemberGetLink
{
71 typedef SinglyLinkedListLink
<Element
> Link
;
74 inline Link
* operator()(Element
* element
) const
76 return &(element
->*LinkMember
);
79 inline const Link
* operator()(const Element
* element
) const
81 return &(element
->*LinkMember
);
87 #define SINGLY_LINKED_LIST_TEMPLATE_LIST \
88 template<typename Element, typename GetLink>
89 #define SINGLY_LINKED_LIST_CLASS_NAME SinglyLinkedList<Element, GetLink>
92 template<typename Element
,
93 typename GetLink
= SinglyLinkedListStandardGetLink
<Element
> >
94 class SinglyLinkedList
{
96 typedef SinglyLinkedList
<Element
, GetLink
> List
;
97 typedef SinglyLinkedListLink
<Element
> Link
;
102 Iterator(const List
* list
)
109 Iterator(const Iterator
& other
)
121 Element
* element
= fNext
;
123 fNext
= fList
->GetNext(fNext
);
127 Iterator
& operator=(const Iterator
& other
)
136 fNext
= fList
->First();
145 SinglyLinkedList() : fFirst(NULL
) {}
146 ~SinglyLinkedList() {}
148 inline bool IsEmpty() const { return (fFirst
== NULL
); }
150 inline void Add(Element
* element
);
151 inline void Remove(Element
* element
);
153 inline void RemoveAll();
154 inline void MakeEmpty() { RemoveAll(); }
156 inline Element
* First() const { return fFirst
; }
157 inline Element
* Head() const { return fFirst
; }
159 inline Element
* RemoveHead();
161 inline Element
* GetNext(Element
* element
) const;
163 inline int32_t Size() const;
166 inline Iterator
GetIterator() const { return Iterator(this); }
171 static GetLink sGetLink
;
178 SINGLY_LINKED_LIST_TEMPLATE_LIST
180 SINGLY_LINKED_LIST_CLASS_NAME::Add(Element
* element
)
182 if (element
!= NULL
) {
183 sGetLink(element
)->next
= fFirst
;
189 SINGLY_LINKED_LIST_TEMPLATE_LIST
191 SINGLY_LINKED_LIST_CLASS_NAME::Remove(Element
* element
)
196 Element
* next
= fFirst
;
197 Element
* last
= NULL
;
198 while (next
!= NULL
&& element
!= next
) {
200 next
= sGetLink(next
)->next
;
203 Link
* elementLink
= sGetLink(element
);
205 fFirst
= elementLink
->next
;
207 sGetLink(last
)->next
= elementLink
->next
;
209 elementLink
->next
= NULL
;
213 SINGLY_LINKED_LIST_TEMPLATE_LIST
215 SINGLY_LINKED_LIST_CLASS_NAME::RemoveAll()
217 Element
* element
= fFirst
;
219 Link
* elLink
= sGetLink(element
);
220 element
= elLink
->next
;
227 SINGLY_LINKED_LIST_TEMPLATE_LIST
229 SINGLY_LINKED_LIST_CLASS_NAME::RemoveHead()
231 Element
* element
= Head();
237 SINGLY_LINKED_LIST_TEMPLATE_LIST
239 SINGLY_LINKED_LIST_CLASS_NAME::GetNext(Element
* element
) const
241 Element
* result
= NULL
;
243 result
= sGetLink(element
)->next
;
248 SINGLY_LINKED_LIST_TEMPLATE_LIST
250 SINGLY_LINKED_LIST_CLASS_NAME::Size() const
253 for (Element
* element
= First(); element
; element
= GetNext(element
))
259 SINGLY_LINKED_LIST_TEMPLATE_LIST
260 GetLink
SINGLY_LINKED_LIST_CLASS_NAME::sGetLink
;
262 } // namespace FSShell
264 using FSShell::SinglyLinkedListLink
;
265 using FSShell::SinglyLinkedListLinkImpl
;
266 using FSShell::SinglyLinkedListStandardGetLink
;
267 using FSShell::SinglyLinkedListMemberGetLink
;
268 using FSShell::SinglyLinkedList
;
270 #endif // __cplusplus
272 #endif // _KERNEL_UTIL_SINGLY_LINKED_LIST_H