2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
27 #define __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
30 //==============================================================================
32 Helps to manipulate singly-linked lists of objects.
34 For objects that are designed to contain a pointer to the subsequent item in the
35 list, this class contains methods to deal with the list. To use it, the ObjectType
36 class that it points to must contain a LinkedListPointer called nextListItem, e.g.
43 // A linkable object must contain a member with this name and type, which must be
44 // accessible by the LinkedListPointer class. (This doesn't mean it has to be public -
45 // you could make your class a friend of a LinkedListPointer<MyObject> instead).
46 LinkedListPointer<MyObject> nextListItem;
49 LinkedListPointer<MyObject> myList;
50 myList.append (new MyObject());
51 myList.append (new MyObject());
53 int numItems = myList.size(); // returns 2
54 MyObject* lastInList = myList.getLast();
57 template <class ObjectType
>
58 class LinkedListPointer
61 //==============================================================================
62 /** Creates a null pointer to an empty list. */
63 LinkedListPointer() noexcept
68 /** Creates a pointer to a list whose head is the item provided. */
69 explicit LinkedListPointer (ObjectType
* const headItem
) noexcept
74 /** Sets this pointer to point to a new list. */
75 LinkedListPointer
& operator= (ObjectType
* const newItem
) noexcept
81 //==============================================================================
82 /** Returns the item which this pointer points to. */
83 inline operator ObjectType
*() const noexcept
88 /** Returns the item which this pointer points to. */
89 inline ObjectType
* get() const noexcept
94 /** Returns the last item in the list which this pointer points to.
95 This will iterate the list and return the last item found. Obviously the speed
96 of this operation will be proportional to the size of the list. If the list is
97 empty the return value will be this object.
98 If you're planning on appending a number of items to your list, it's much more
99 efficient to use the Appender class than to repeatedly call getLast() to find the end.
101 LinkedListPointer
& getLast() noexcept
103 LinkedListPointer
* l
= this;
105 while (l
->item
!= nullptr)
106 l
= &(l
->item
->nextListItem
);
111 /** Returns the number of items in the list.
112 Obviously with a simple linked list, getting the size involves iterating the list, so
113 this can be a lengthy operation - be careful when using this method in your code.
115 int size() const noexcept
119 for (ObjectType
* i
= item
; i
!= nullptr; i
= i
->nextListItem
)
125 /** Returns the item at a given index in the list.
126 Since the only way to find an item is to iterate the list, this operation can obviously
127 be slow, depending on its size, so you should be careful when using this in algorithms.
129 LinkedListPointer
& operator[] (int index
) noexcept
131 LinkedListPointer
* l
= this;
133 while (--index
>= 0 && l
->item
!= nullptr)
134 l
= &(l
->item
->nextListItem
);
139 /** Returns the item at a given index in the list.
140 Since the only way to find an item is to iterate the list, this operation can obviously
141 be slow, depending on its size, so you should be careful when using this in algorithms.
143 const LinkedListPointer
& operator[] (int index
) const noexcept
145 const LinkedListPointer
* l
= this;
147 while (--index
>= 0 && l
->item
!= nullptr)
148 l
= &(l
->item
->nextListItem
);
153 /** Returns true if the list contains the given item. */
154 bool contains (const ObjectType
* const itemToLookFor
) const noexcept
156 for (ObjectType
* i
= item
; i
!= nullptr; i
= i
->nextListItem
)
157 if (itemToLookFor
== i
)
163 //==============================================================================
164 /** Inserts an item into the list, placing it before the item that this pointer
167 void insertNext (ObjectType
* const newItem
)
169 jassert (newItem
!= nullptr);
170 jassert (newItem
->nextListItem
== nullptr);
171 newItem
->nextListItem
= item
;
175 /** Inserts an item at a numeric index in the list.
176 Obviously this will involve iterating the list to find the item at the given index,
177 so be careful about the impact this may have on execution time.
179 void insertAtIndex (int index
, ObjectType
* newItem
)
181 jassert (newItem
!= nullptr);
182 LinkedListPointer
* l
= this;
184 while (index
!= 0 && l
->item
!= nullptr)
186 l
= &(l
->item
->nextListItem
);
190 l
->insertNext (newItem
);
193 /** Replaces the object that this pointer points to, appending the rest of the list to
194 the new object, and returning the old one.
196 ObjectType
* replaceNext (ObjectType
* const newItem
) noexcept
198 jassert (newItem
!= nullptr);
199 jassert (newItem
->nextListItem
== nullptr);
201 ObjectType
* const oldItem
= item
;
203 item
->nextListItem
= oldItem
->nextListItem
.item
;
204 oldItem
->nextListItem
= (ObjectType
*) 0;
208 /** Adds an item to the end of the list.
210 This operation involves iterating the whole list, so can be slow - if you need to
211 append a number of items to your list, it's much more efficient to use the Appender
212 class than to repeatedly call append().
214 void append (ObjectType
* const newItem
)
216 getLast().item
= newItem
;
219 /** Creates copies of all the items in another list and adds them to this one.
220 This will use the ObjectType's copy constructor to try to create copies of each
221 item in the other list, and appends them to this list.
223 void addCopyOfList (const LinkedListPointer
& other
)
225 LinkedListPointer
* insertPoint
= this;
227 for (ObjectType
* i
= other
.item
; i
!= nullptr; i
= i
->nextListItem
)
229 insertPoint
->insertNext (new ObjectType (*i
));
230 insertPoint
= &(insertPoint
->item
->nextListItem
);
234 /** Removes the head item from the list.
235 This won't delete the object that is removed, but returns it, so the caller can
236 delete it if necessary.
238 ObjectType
* removeNext() noexcept
240 ObjectType
* const oldItem
= item
;
242 if (oldItem
!= nullptr)
244 item
= oldItem
->nextListItem
;
245 oldItem
->nextListItem
= (ObjectType
*) 0;
251 /** Removes a specific item from the list.
252 Note that this will not delete the item, it simply unlinks it from the list.
254 void remove (ObjectType
* const itemToRemove
)
256 LinkedListPointer
* const l
= findPointerTo (itemToRemove
);
262 /** Iterates the list, calling the delete operator on all of its elements and
263 leaving this pointer empty.
267 while (item
!= nullptr)
269 ObjectType
* const oldItem
= item
;
270 item
= oldItem
->nextListItem
;
275 /** Finds a pointer to a given item.
276 If the item is found in the list, this returns the pointer that points to it. If
277 the item isn't found, this returns null.
279 LinkedListPointer
* findPointerTo (ObjectType
* const itemToLookFor
) noexcept
281 LinkedListPointer
* l
= this;
283 while (l
->item
!= nullptr)
285 if (l
->item
== itemToLookFor
)
288 l
= &(l
->item
->nextListItem
);
294 /** Copies the items in the list to an array.
295 The destArray must contain enough elements to hold the entire list - no checks are
298 void copyToArray (ObjectType
** destArray
) const noexcept
300 jassert (destArray
!= nullptr);
302 for (ObjectType
* i
= item
; i
!= nullptr; i
= i
->nextListItem
)
306 //==============================================================================
308 Allows efficient repeated insertions into a list.
310 You can create an Appender object which points to the last element in your
311 list, and then repeatedly call Appender::append() to add items to the end
312 of the list in O(1) time.
317 /** Creates an appender which will add items to the given list.
319 Appender (LinkedListPointer
& endOfListPointer
) noexcept
320 : endOfList (&endOfListPointer
)
322 // This can only be used to add to the end of a list.
323 jassert (endOfListPointer
.item
== nullptr);
326 /** Appends an item to the list. */
327 void append (ObjectType
* const newItem
) noexcept
329 *endOfList
= newItem
;
330 endOfList
= &(newItem
->nextListItem
);
334 LinkedListPointer
* endOfList
;
336 JUCE_DECLARE_NON_COPYABLE (Appender
);
340 //==============================================================================
343 JUCE_DECLARE_NON_COPYABLE (LinkedListPointer
);
347 #endif // __JUCE_LINKEDLISTPOINTER_JUCEHEADER__