Bumping manifests a=b2g-bump
[gecko.git] / xpcom / glue / nsDeque.h
blob279af93b6dd5258ec9d74208b0f206f2517dacf0
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /**
8 * MODULE NOTES:
10 * The Deque is a very small, very efficient container object
11 * than can hold elements of type void*, offering the following features:
12 * Its interface supports pushing and popping of elements.
13 * It can iterate (via an interator class) its elements.
14 * When full, it can efficiently resize dynamically.
17 * NOTE: The only bit of trickery here is that this deque is
18 * built upon a ring-buffer. Like all ring buffers, the first
19 * element may not be at index[0]. The mOrigin member determines
20 * where the first child is. This point is quietly hidden from
21 * customers of this class.
25 #ifndef _NSDEQUE
26 #define _NSDEQUE
28 #include "nscore.h"
29 #include "nsDebug.h"
30 #include "mozilla/Attributes.h"
31 #include "mozilla/fallible.h"
32 #include "mozilla/MemoryReporting.h"
34 /**
35 * The nsDequeFunctor class is used when you want to create
36 * callbacks between the deque and your generic code.
37 * Use these objects in a call to ForEach();
41 class nsDequeFunctor
43 public:
44 virtual void* operator()(void* aObject) = 0;
45 virtual ~nsDequeFunctor() {}
48 /******************************************************
49 * Here comes the nsDeque class itself...
50 ******************************************************/
52 /**
53 * The deque (double-ended queue) class is a common container type,
54 * whose behavior mimics a line in your favorite checkout stand.
55 * Classic CS describes the common behavior of a queue as FIFO.
56 * A deque allows insertion and removal at both ends of
57 * the container.
59 * The deque stores pointers to items.
62 class nsDequeIterator;
64 class nsDeque
66 friend class nsDequeIterator;
67 typedef mozilla::fallible_t fallible_t;
68 public:
69 explicit nsDeque(nsDequeFunctor* aDeallocator = nullptr);
70 ~nsDeque();
72 /**
73 * Returns the number of elements currently stored in
74 * this deque.
76 * @return number of elements currently in the deque
78 inline int32_t GetSize() const { return mSize; }
80 /**
81 * Appends new member at the end of the deque.
83 * @param item to store in deque
85 void Push(void* aItem)
87 if (!Push(aItem, fallible_t())) {
88 NS_ABORT_OOM(mSize * sizeof(void*));
92 NS_WARN_UNUSED_RESULT bool Push(void* aItem, const fallible_t&);
94 /**
95 * Inserts new member at the front of the deque.
97 * @param item to store in deque
99 void PushFront(void* aItem)
101 if (!PushFront(aItem, fallible_t())) {
102 NS_ABORT_OOM(mSize * sizeof(void*));
106 NS_WARN_UNUSED_RESULT bool PushFront(void* aItem, const fallible_t&);
109 * Remove and return the last item in the container.
111 * @return the item that was the last item in container
113 void* Pop();
116 * Remove and return the first item in the container.
118 * @return the item that was first item in container
120 void* PopFront();
123 * Retrieve the bottom item without removing it.
125 * @return the first item in container
128 void* Peek();
130 * Return topmost item without removing it.
132 * @return the first item in container
134 void* PeekFront();
137 * Retrieve a member from the deque without removing it.
139 * @param index of desired item
140 * @return element in list
142 void* ObjectAt(int aIndex) const;
145 * Removes and returns the a member from the deque.
147 * @param index of desired item
148 * @return element which was removed
150 void* RemoveObjectAt(int aIndex);
153 * Remove all items from container without destroying them.
155 void Empty();
158 * Remove and delete all items from container.
159 * Deletes are handled by the deallocator nsDequeFunctor
160 * which is specified at deque construction.
162 void Erase();
165 * Creates a new iterator, pointing to the first
166 * item in the deque.
168 * @return new dequeIterator
170 nsDequeIterator Begin() const;
173 * Creates a new iterator, pointing to the last
174 * item in the deque.
176 * @return new dequeIterator
178 nsDequeIterator End() const;
180 void* Last() const;
183 * Call this method when you want to iterate all the
184 * members of the container, passing a functor along
185 * to call your code.
187 * @param aFunctor object to call for each member
189 void ForEach(nsDequeFunctor& aFunctor) const;
192 * Call this method when you want to iterate all the
193 * members of the container, calling the functor you
194 * passed with each member. This process will interrupt
195 * if your function returns non 0 to this method.
197 * @param aFunctor object to call for each member
198 * @return first nonzero result of aFunctor or 0.
200 const void* FirstThat(nsDequeFunctor& aFunctor) const;
202 void SetDeallocator(nsDequeFunctor* aDeallocator);
204 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
205 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
207 protected:
208 int32_t mSize;
209 int32_t mCapacity;
210 int32_t mOrigin;
211 nsDequeFunctor* mDeallocator;
212 void* mBuffer[8];
213 void** mData;
215 private:
218 * Copy constructor (PRIVATE)
220 * @param aOther another deque
222 nsDeque(const nsDeque& aOther);
225 * Deque assignment operator (PRIVATE)
227 * @param aOther another deque
228 * @return *this
230 nsDeque& operator=(const nsDeque& aOther);
232 bool GrowCapacity();
235 /******************************************************
236 * Here comes the nsDequeIterator class...
237 ******************************************************/
239 class nsDequeIterator
241 public:
243 * DequeIterator is an object that knows how to iterate
244 * (forward and backward) through a Deque. Normally,
245 * you don't need to do this, but there are some special
246 * cases where it is pretty handy.
248 * One warning: the iterator is not bound to an item,
249 * it is bound to an index, so if you insert or remove
250 * from the beginning while using an iterator
251 * (which is not recommended) then the iterator will
252 * point to a different item. @see GetCurrent()
254 * Here you go.
256 * @param aQueue is the deque object to be iterated
257 * @param aIndex is the starting position for your iteration
259 explicit nsDequeIterator(const nsDeque& aQueue, int aIndex = 0);
262 * Create a copy of a DequeIterator
264 * @param aCopy is another iterator to copy from
266 nsDequeIterator(const nsDequeIterator& aCopy);
269 * Moves iterator to first element in the deque
270 * @return *this
272 nsDequeIterator& First();
275 * Standard assignment operator for dequeiterator
276 * @param aCopy is another iterator to copy from
277 * @return *this
279 nsDequeIterator& operator=(const nsDequeIterator& aCopy);
282 * preform ! operation against two iterators to test for equivalence
283 * (or lack thereof)!
285 * @param aIter is the object to be compared to
286 * @return TRUE if NOT equal.
288 bool operator!=(nsDequeIterator& aIter);
291 * Compare two iterators for increasing order.
293 * @param aIter is the other iterator to be compared to
294 * @return TRUE if this object points to an element before
295 * the element pointed to by aIter.
296 * FALSE if this and aIter are not iterating over
297 * the same deque.
299 bool operator<(nsDequeIterator& aIter);
302 * Compare two iterators for equivalence.
304 * @param aIter is the other iterator to be compared to
305 * @return TRUE if EQUAL
307 bool operator==(nsDequeIterator& aIter);
310 * Compare two iterators for non strict decreasing order.
312 * @param aIter is the other iterator to be compared to
313 * @return TRUE if this object points to the same element, or
314 * an element after the element pointed to by aIter.
315 * FALSE if this and aIter are not iterating over
316 * the same deque.
318 bool operator>=(nsDequeIterator& aIter);
321 * Pre-increment operator
322 * Iterator will advance one index towards the end.
324 * @return object_at(++index)
326 void* operator++();
329 * Post-increment operator
330 * Iterator will advance one index towards the end.
332 * @param param is ignored
333 * @return object_at(mIndex++)
335 void* operator++(int);
338 * Pre-decrement operator
339 * Iterator will advance one index towards the beginning.
341 * @return object_at(--index)
343 void* operator--();
346 * Post-decrement operator
347 * Iterator will advance one index towards the beginning.
349 * @param param is ignored
350 * @return object_at(index--)
352 void* operator--(int);
355 * Retrieve the the iterator's notion of current node.
357 * Note that the iterator floats, so you don't need to do:
358 * <code>++iter; aDeque.PopFront();</code>
359 * Unless you actually want your iterator to jump 2 positions
360 * relative to its origin.
362 * Picture: [1 2i 3 4]
363 * PopFront()
364 * Picture: [2 3i 4]
365 * Note that I still happily points to object at the second index.
367 * @return object at i'th index
369 void* GetCurrent();
372 * Call this method when you want to iterate all the
373 * members of the container, passing a functor along
374 * to call your code.
376 * @param aFunctor object to call for each member
377 * @return *this
379 void ForEach(nsDequeFunctor& aFunctor) const;
382 * Call this method when you want to iterate all the
383 * members of the container, calling the functor you
384 * passed with each member. This process will interrupt
385 * if your function returns non 0 to this method.
387 * @param aFunctor object to call for each member
388 * @return first nonzero result of aFunctor or 0.
390 const void* FirstThat(nsDequeFunctor& aFunctor) const;
392 protected:
394 int32_t mIndex;
395 const nsDeque& mDeque;
397 #endif