Add remaining files
[juce-lv2.git] / juce / source / src / containers / juce_LinkedListPointer.h
blob826c8c4adfb0dcb47949a07090c440945931e60c
1 /*
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 //==============================================================================
31 /**
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.
38 @code
39 struct MyObject
41 int x, y, z;
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();
55 @endcode
57 template <class ObjectType>
58 class LinkedListPointer
60 public:
61 //==============================================================================
62 /** Creates a null pointer to an empty list. */
63 LinkedListPointer() noexcept
64 : item (nullptr)
68 /** Creates a pointer to a list whose head is the item provided. */
69 explicit LinkedListPointer (ObjectType* const headItem) noexcept
70 : item (headItem)
74 /** Sets this pointer to point to a new list. */
75 LinkedListPointer& operator= (ObjectType* const newItem) noexcept
77 item = newItem;
78 return *this;
81 //==============================================================================
82 /** Returns the item which this pointer points to. */
83 inline operator ObjectType*() const noexcept
85 return item;
88 /** Returns the item which this pointer points to. */
89 inline ObjectType* get() const noexcept
91 return item;
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);
108 return *l;
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
117 int total = 0;
119 for (ObjectType* i = item; i != nullptr; i = i->nextListItem)
120 ++total;
122 return total;
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);
136 return *l;
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);
150 return *l;
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)
158 return true;
160 return false;
163 //==============================================================================
164 /** Inserts an item into the list, placing it before the item that this pointer
165 currently points to.
167 void insertNext (ObjectType* const newItem)
169 jassert (newItem != nullptr);
170 jassert (newItem->nextListItem == nullptr);
171 newItem->nextListItem = item;
172 item = newItem;
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);
187 --index;
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;
202 item = newItem;
203 item->nextListItem = oldItem->nextListItem.item;
204 oldItem->nextListItem = (ObjectType*) 0;
205 return oldItem;
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;
248 return oldItem;
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);
258 if (l != nullptr)
259 l->removeNext();
262 /** Iterates the list, calling the delete operator on all of its elements and
263 leaving this pointer empty.
265 void deleteAll()
267 while (item != nullptr)
269 ObjectType* const oldItem = item;
270 item = oldItem->nextListItem;
271 delete oldItem;
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)
286 return l;
288 l = &(l->item->nextListItem);
291 return nullptr;
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
296 made for this!
298 void copyToArray (ObjectType** destArray) const noexcept
300 jassert (destArray != nullptr);
302 for (ObjectType* i = item; i != nullptr; i = i->nextListItem)
303 *destArray++ = i;
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.
314 class Appender
316 public:
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);
333 private:
334 LinkedListPointer* endOfList;
336 JUCE_DECLARE_NON_COPYABLE (Appender);
339 private:
340 //==============================================================================
341 ObjectType* item;
343 JUCE_DECLARE_NON_COPYABLE (LinkedListPointer);
347 #endif // __JUCE_LINKEDLISTPOINTER_JUCEHEADER__