nsDeque.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. * MODULE NOTES:
  7. *
  8. * The Deque is a very small, very efficient container object
  9. * than can hold elements of type void*, offering the following features:
  10. * Its interface supports pushing and popping of elements.
  11. * It can iterate (via an interator class) its elements.
  12. * When full, it can efficiently resize dynamically.
  13. *
  14. *
  15. * NOTE: The only bit of trickery here is that this deque is
  16. * built upon a ring-buffer. Like all ring buffers, the first
  17. * element may not be at index[0]. The mOrigin member determines
  18. * where the first child is. This point is quietly hidden from
  19. * customers of this class.
  20. *
  21. */
  22. #ifndef _NSDEQUE
  23. #define _NSDEQUE
  24. #include "nscore.h"
  25. #include "nsDebug.h"
  26. #include "mozilla/Attributes.h"
  27. #include "mozilla/fallible.h"
  28. #include "mozilla/MemoryReporting.h"
  29. /**
  30. * The nsDequeFunctor class is used when you want to create
  31. * callbacks between the deque and your generic code.
  32. * Use these objects in a call to ForEach();
  33. *
  34. */
  35. class nsDequeFunctor
  36. {
  37. public:
  38. virtual void* operator()(void* aObject) = 0;
  39. virtual ~nsDequeFunctor() {}
  40. };
  41. /******************************************************
  42. * Here comes the nsDeque class itself...
  43. ******************************************************/
  44. /**
  45. * The deque (double-ended queue) class is a common container type,
  46. * whose behavior mimics a line in your favorite checkout stand.
  47. * Classic CS describes the common behavior of a queue as FIFO.
  48. * A deque allows insertion and removal at both ends of
  49. * the container.
  50. *
  51. * The deque stores pointers to items.
  52. */
  53. class nsDequeIterator;
  54. class nsDeque
  55. {
  56. typedef mozilla::fallible_t fallible_t;
  57. public:
  58. explicit nsDeque(nsDequeFunctor* aDeallocator = nullptr);
  59. ~nsDeque();
  60. /**
  61. * Returns the number of elements currently stored in
  62. * this deque.
  63. *
  64. * @return number of elements currently in the deque
  65. */
  66. inline size_t GetSize() const { return mSize; }
  67. /**
  68. * Appends new member at the end of the deque.
  69. *
  70. * @param item to store in deque
  71. */
  72. void Push(void* aItem)
  73. {
  74. if (!Push(aItem, mozilla::fallible)) {
  75. NS_ABORT_OOM(mSize * sizeof(void*));
  76. }
  77. }
  78. MOZ_MUST_USE bool Push(void* aItem, const fallible_t&);
  79. /**
  80. * Inserts new member at the front of the deque.
  81. *
  82. * @param item to store in deque
  83. */
  84. void PushFront(void* aItem)
  85. {
  86. if (!PushFront(aItem, mozilla::fallible)) {
  87. NS_ABORT_OOM(mSize * sizeof(void*));
  88. }
  89. }
  90. MOZ_MUST_USE bool PushFront(void* aItem, const fallible_t&);
  91. /**
  92. * Remove and return the last item in the container.
  93. *
  94. * @return the item that was the last item in container
  95. */
  96. void* Pop();
  97. /**
  98. * Remove and return the first item in the container.
  99. *
  100. * @return the item that was first item in container
  101. */
  102. void* PopFront();
  103. /**
  104. * Retrieve the bottom item without removing it.
  105. *
  106. * @return the first item in container
  107. */
  108. void* Peek() const;
  109. /**
  110. * Return topmost item without removing it.
  111. *
  112. * @return the first item in container
  113. */
  114. void* PeekFront() const;
  115. /**
  116. * Retrieve a member from the deque without removing it.
  117. *
  118. * @param index of desired item
  119. * @return element in list
  120. */
  121. void* ObjectAt(size_t aIndex) const;
  122. /**
  123. * Remove and delete all items from container.
  124. * Deletes are handled by the deallocator nsDequeFunctor
  125. * which is specified at deque construction.
  126. */
  127. void Erase();
  128. /**
  129. * Call this method when you want to iterate all the
  130. * members of the container, passing a functor along
  131. * to call your code.
  132. *
  133. * @param aFunctor object to call for each member
  134. */
  135. void ForEach(nsDequeFunctor& aFunctor) const;
  136. size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  137. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  138. protected:
  139. size_t mSize;
  140. size_t mCapacity;
  141. size_t mOrigin;
  142. nsDequeFunctor* mDeallocator;
  143. void* mBuffer[8];
  144. void** mData;
  145. private:
  146. /**
  147. * Copy constructor (PRIVATE)
  148. *
  149. * @param aOther another deque
  150. */
  151. nsDeque(const nsDeque& aOther);
  152. /**
  153. * Deque assignment operator (PRIVATE)
  154. *
  155. * @param aOther another deque
  156. * @return *this
  157. */
  158. nsDeque& operator=(const nsDeque& aOther);
  159. bool GrowCapacity();
  160. void SetDeallocator(nsDequeFunctor* aDeallocator);
  161. /**
  162. * Remove all items from container without destroying them.
  163. */
  164. void Empty();
  165. };
  166. #endif