3 // Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
23 // Except as contained in this notice, the name of a copyright holder shall
24 // not be used in advertising or otherwise to promote the sale, use or other
25 // dealings in this Software without prior written authorization of the
34 template<typename Value
>
35 struct SLListStandardNode
{
36 SLListStandardNode(const Value
&a
)
43 SLListStandardNode
<Value
> *next
;
46 // SLListStandardNodeAllocator
47 template<typename Value
, typename Node
>
48 class SLListStandardNodeAllocator
51 inline Node
*Allocate(const Value
&a
) const
53 return new(nothrow
) SLListStandardNode
<Value
>(a
);
56 inline void Free(Node
*node
) const
62 // SLListValueNodeAllocator
63 template<typename Value
, typename Node
>
64 class SLListValueNodeAllocator
67 inline Node
*Allocate(const Value
&a
) const
72 inline void Free(Node
*node
) const
77 // SLListStandardGetValue
78 template<typename Value
, typename Node
>
79 class SLListStandardGetValue
82 inline Value
&operator()(Node
*node
) const
88 // SLListValueNodeGetValue
89 template<typename Value
, typename Node
>
90 class SLListValueNodeGetValue
93 inline Value
&operator()(Node
*node
) const
100 #define SL_LIST_TEMPLATE_LIST template<typename Value, typename Node, \
101 typename NodeAllocator, typename GetValue>
102 #define SL_LIST_CLASS_NAME SLList<Value, Node, NodeAllocator, GetValue>
105 template<typename Value
, typename Node
= SLListStandardNode
<Value
>,
106 typename NodeAllocator
= SLListStandardNodeAllocator
<Value
, Node
>,
107 typename GetValue
= SLListStandardGetValue
<Value
, Node
> >
114 SLList(const NodeAllocator
&nodeAllocator
, const GetValue
&getValue
);
117 bool Insert(const Value
&value
, Iterator
*iterator
= NULL
);
118 bool Remove(const Value
&value
);
119 void Remove(Iterator
&iterator
);
122 bool Find(const Value
&value
, Iterator
*iterator
= NULL
) const;
123 void GetIterator(Iterator
*iterator
) const;
126 friend class Iterator
;
129 NodeAllocator fNodeAllocator
;
134 SL_LIST_TEMPLATE_LIST
135 class SL_LIST_CLASS_NAME::Iterator
{
137 Iterator() : fList(NULL
), fCurrent(NULL
) {}
140 inline Value
*GetCurrent()
142 return (fList
&& fCurrent
? &fList
->fGetValue(fCurrent
) : NULL
);
145 inline Value
*GetNext()
148 fCurrent
= fCurrent
->next
;
155 fList
->Remove(*this);
159 friend class SL_LIST_CLASS_NAME
;
161 inline void _SetTo(SL_LIST_CLASS_NAME
*list
, Node
*previous
, Node
*node
)
164 fPrevious
= previous
;
168 inline SL_LIST_CLASS_NAME
*_GetList() const { return fList
; }
169 inline Node
*_GetPreviousNode() const { return fPrevious
; }
170 inline Node
*_GetCurrentNode() const { return fCurrent
; }
173 SL_LIST_CLASS_NAME
*fList
;
179 SL_LIST_TEMPLATE_LIST
180 SL_LIST_CLASS_NAME::SLList()
188 SL_LIST_TEMPLATE_LIST
189 SL_LIST_CLASS_NAME::SLList(const NodeAllocator
&nodeAllocator
,
190 const GetValue
&getValue
)
192 fNodeAllocator(nodeAllocator
),
198 SL_LIST_TEMPLATE_LIST
199 SL_LIST_CLASS_NAME::~SLList()
205 SL_LIST_TEMPLATE_LIST
207 SL_LIST_CLASS_NAME::Insert(const Value
&value
, Iterator
*iterator
)
209 Node
*node
= fNodeAllocator
.Allocate(value
);
214 iterator
->_SetTo(this, NULL
, node
);
220 SL_LIST_TEMPLATE_LIST
222 SL_LIST_CLASS_NAME::Remove(const Value
&value
)
225 bool result
= Find(value
, &iterator
);
232 SL_LIST_TEMPLATE_LIST
234 SL_LIST_CLASS_NAME::Remove(Iterator
&iterator
)
236 Node
*node
= iterator
._GetCurrentNode();
237 if (iterator
._GetList() == this && node
) {
238 Node
*previous
= iterator
._GetPreviousNode();
239 iterator
._SetTo(this, previous
, node
->next
);
241 previous
->next
= node
->next
;
244 fNodeAllocator
.Free(node
);
249 SL_LIST_TEMPLATE_LIST
251 SL_LIST_CLASS_NAME::RemoveAll()
253 for (Node
*node
= fHead
; node
; ) {
254 Node
*next
= node
->next
;
255 fNodeAllocator
.Free(node
);
262 SL_LIST_TEMPLATE_LIST
264 SL_LIST_CLASS_NAME::Find(const Value
&value
, Iterator
*iterator
) const
267 Node
*previous
= NULL
;
268 while (node
&& fGetValue(node
) != value
) {
272 if (node
&& iterator
) {
273 iterator
->_SetTo(const_cast<SL_LIST_CLASS_NAME
*>(this), previous
,
280 SL_LIST_TEMPLATE_LIST
282 SL_LIST_CLASS_NAME::GetIterator(Iterator
*iterator
) const
285 iterator
->_SetTo(const_cast<SL_LIST_CLASS_NAME
*>(this), NULL
, fHead
);