gecko-dev/xpcom/glue/nsDeque.h

392 строки
10 KiB
C
Исходник Обычный вид История

1998-04-22 22:28:48 +04:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2012-05-21 15:12:37 +04:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1998-04-22 22:28:48 +04:00
/**
* MODULE NOTES:
*
1998-04-22 22:28:48 +04:00
* The Deque is a very small, very efficient container object
* than can hold elements of type void*, offering the following features:
* Its interface supports pushing and popping of elements.
* It can iterate (via an interator class) its elements.
* When full, it can efficiently resize dynamically.
1998-04-22 22:28:48 +04:00
*
*
* NOTE: The only bit of trickery here is that this deque is
* built upon a ring-buffer. Like all ring buffers, the first
* element may not be at index[0]. The mOrigin member determines
* where the first child is. This point is quietly hidden from
1998-04-22 22:28:48 +04:00
* customers of this class.
*
1998-04-22 22:28:48 +04:00
*/
#ifndef _NSDEQUE
#define _NSDEQUE
#include "nscore.h"
#include "nsDebug.h"
#include "mozilla/Attributes.h"
#include "mozilla/fallible.h"
#include "mozilla/MemoryReporting.h"
1998-04-22 22:28:48 +04:00
/**
* The nsDequeFunctor class is used when you want to create
1998-04-22 22:28:48 +04:00
* callbacks between the deque and your generic code.
* Use these objects in a call to ForEach();
*
*/
class nsDequeFunctor{
1998-04-22 22:28:48 +04:00
public:
virtual void* operator()(void* anObject)=0;
virtual ~nsDequeFunctor() {}
1998-04-22 22:28:48 +04:00
};
/******************************************************
* Here comes the nsDeque class itself...
******************************************************/
/**
* The deque (double-ended queue) class is a common container type,
1998-04-22 22:28:48 +04:00
* whose behavior mimics a line in your favorite checkout stand.
* Classic CS describes the common behavior of a queue as FIFO.
* A deque allows insertion and removal at both ends of
* the container.
1998-04-22 22:28:48 +04:00
*
* The deque stores pointers to items.
1998-04-22 22:28:48 +04:00
*/
class nsDequeIterator;
class NS_COM_GLUE nsDeque {
friend class nsDequeIterator;
typedef mozilla::fallible_t fallible_t;
1998-04-22 22:28:48 +04:00
public:
nsDeque(nsDequeFunctor* aDeallocator = nullptr);
~nsDeque();
1998-04-22 22:28:48 +04:00
/**
* Returns the number of elements currently stored in
* this deque.
*
* @return number of elements currently in the deque
1998-04-22 22:28:48 +04:00
*/
inline int32_t GetSize() const {return mSize;}
1998-04-22 22:28:48 +04:00
/**
* Appends new member at the end of the deque.
1998-04-22 22:28:48 +04:00
*
* @param item to store in deque
1998-04-22 22:28:48 +04:00
*/
void Push(void* aItem) {
if (!Push(aItem, fallible_t())) {
NS_ABORT_OOM(mSize);
}
}
bool Push(void* aItem, const fallible_t&) NS_WARN_UNUSED_RESULT;
/**
* Inserts new member at the front of the deque.
*
* @param item to store in deque
*/
void PushFront(void* aItem) {
if (!PushFront(aItem, fallible_t())) {
NS_ABORT_OOM(mSize);
}
}
bool PushFront(void* aItem, const fallible_t&) NS_WARN_UNUSED_RESULT;
1998-04-22 22:28:48 +04:00
/**
* Remove and return the last item in the container.
*
* @return the item that was the last item in container
1998-04-22 22:28:48 +04:00
*/
void* Pop();
1998-08-05 05:59:34 +04:00
/**
* Remove and return the first item in the container.
*
* @return the item that was first item in container
1998-08-05 05:59:34 +04:00
*/
void* PopFront();
/**
* Retrieve the bottom item without removing it.
*
* @return the first item in container
*/
void* Peek();
1998-04-22 22:28:48 +04:00
/**
* Return topmost item without removing it.
*
* @return the first item in container
1998-04-22 22:28:48 +04:00
*/
void* PeekFront();
/**
* Retrieve the i'th member from the deque without removing it.
*
* @param index of desired item
* @return i'th element in list
*/
void* ObjectAt(int aIndex) const;
/**
* Removes and returns the i'th member from the deque.
*
* @param index of desired item
* @return the element which was removed
*/
void* RemoveObjectAt(int aIndex);
1998-04-22 22:28:48 +04:00
/**
* Remove all items from container without destroying them.
1998-04-22 22:28:48 +04:00
*/
void Empty();
1998-04-22 22:28:48 +04:00
/**
* Remove and delete all items from container.
* Deletes are handled by the deallocator nsDequeFunctor
* which is specified at deque construction.
1998-04-22 22:28:48 +04:00
*/
void Erase();
1998-04-22 22:28:48 +04:00
/**
* Creates a new iterator, pointing to the first
* item in the deque.
1998-04-22 22:28:48 +04:00
*
* @return new dequeIterator
*/
nsDequeIterator Begin() const;
1998-04-22 22:28:48 +04:00
/**
* Creates a new iterator, pointing to the last
* item in the deque.
1998-04-22 22:28:48 +04:00
*
* @return new dequeIterator
*/
nsDequeIterator End() const;
void* Last() const;
1998-04-22 22:28:48 +04:00
/**
* Call this method when you want to iterate all the
1998-04-22 22:28:48 +04:00
* members of the container, passing a functor along
* to call your code.
*
* @param aFunctor object to call for each member
*/
void ForEach(nsDequeFunctor& aFunctor) const;
1998-08-05 05:59:34 +04:00
/**
* Call this method when you want to iterate all the
* members of the container, calling the functor you
* passed with each member. This process will interrupt
* if your function returns non 0 to this method.
1998-08-05 05:59:34 +04:00
*
* @param aFunctor object to call for each member
* @return first nonzero result of aFunctor or 0.
1998-08-05 05:59:34 +04:00
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
1998-04-22 22:28:48 +04:00
1999-02-26 10:23:56 +03:00
void SetDeallocator(nsDequeFunctor* aDeallocator);
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1998-04-22 22:28:48 +04:00
protected:
int32_t mSize;
int32_t mCapacity;
int32_t mOrigin;
nsDequeFunctor* mDeallocator;
1999-07-16 21:31:00 +04:00
void* mBuffer[8];
void** mData;
private:
1998-04-22 22:28:48 +04:00
/**
* Copy constructor (PRIVATE)
*
* @param another deque
1998-04-22 22:28:48 +04:00
*/
nsDeque(const nsDeque& other);
1998-04-22 22:28:48 +04:00
/**
* Deque assignment operator (PRIVATE)
*
* @param another deque
* @return *this
*/
nsDeque& operator=(const nsDeque& anOther);
bool GrowCapacity();
1998-04-22 22:28:48 +04:00
};
/******************************************************
* Here comes the nsDequeIterator class...
******************************************************/
class NS_COM_GLUE nsDequeIterator {
1998-04-22 22:28:48 +04:00
public:
/**
* DequeIterator is an object that knows how to iterate
* (forward and backward) through a Deque. Normally,
* you don't need to do this, but there are some special
* cases where it is pretty handy.
*
* One warning: the iterator is not bound to an item,
* it is bound to an index, so if you insert or remove
* from the beginning while using an iterator
* (which is not recommended) then the iterator will
* point to a different item. @see GetCurrent()
*
* Here you go.
1998-04-22 22:28:48 +04:00
*
* @param aQueue is the deque object to be iterated
* @param aIndex is the starting position for your iteration
1998-04-22 22:28:48 +04:00
*/
nsDequeIterator(const nsDeque& aQueue, int aIndex=0);
1998-04-22 22:28:48 +04:00
/**
* Create a copy of a DequeIterator
1998-04-22 22:28:48 +04:00
*
* @param aCopy is another iterator to copy from
1998-04-22 22:28:48 +04:00
*/
nsDequeIterator(const nsDequeIterator& aCopy);
1998-08-21 06:03:56 +04:00
/**
* Moves iterator to first element in the deque
* @return *this
1998-08-21 06:03:56 +04:00
*/
nsDequeIterator& First();
1998-08-21 06:03:56 +04:00
1998-04-22 22:28:48 +04:00
/**
* Standard assignment operator for dequeiterator
* @param aCopy is another iterator to copy from
* @return *this
1998-04-22 22:28:48 +04:00
*/
nsDequeIterator& operator=(const nsDequeIterator& aCopy);
1998-04-22 22:28:48 +04:00
/**
* preform ! operation against two iterators to test for equivalence
1998-04-22 22:28:48 +04:00
* (or lack thereof)!
*
* @param aIter is the object to be compared to
1998-04-22 22:28:48 +04:00
* @return TRUE if NOT equal.
*/
bool operator!=(nsDequeIterator& aIter);
1998-04-30 09:55:51 +04:00
/**
* Compare two iterators for increasing order.
1998-04-30 09:55:51 +04:00
*
* @param aIter is the other iterator to be compared to
* @return TRUE if this object points to an element before
* the element pointed to by aIter.
* FALSE if this and aIter are not iterating over
* the same deque.
1998-04-30 09:55:51 +04:00
*/
bool operator<(nsDequeIterator& aIter);
1998-04-30 09:55:51 +04:00
1998-04-22 22:28:48 +04:00
/**
* Compare two iterators for equivalence.
1998-04-22 22:28:48 +04:00
*
* @param aIter is the other iterator to be compared to
1998-04-22 22:28:48 +04:00
* @return TRUE if EQUAL
*/
bool operator==(nsDequeIterator& aIter);
1998-04-30 09:55:51 +04:00
/**
* Compare two iterators for non strict decreasing order.
1998-04-30 09:55:51 +04:00
*
* @param aIter is the other iterator to be compared to
* @return TRUE if this object points to the same element, or
* an element after the element pointed to by aIter.
* FALSE if this and aIter are not iterating over
* the same deque.
1998-04-30 09:55:51 +04:00
*/
bool operator>=(nsDequeIterator& aIter);
1998-04-22 22:28:48 +04:00
/**
* Pre-increment operator
* Iterator will advance one index towards the end.
1998-04-22 22:28:48 +04:00
*
* @return object_at(++index)
1998-04-22 22:28:48 +04:00
*/
void* operator++();
/**
* Post-increment operator
* Iterator will advance one index towards the end.
1998-04-22 22:28:48 +04:00
*
* @param param is ignored
* @return object_at(mIndex++)
1998-04-22 22:28:48 +04:00
*/
void* operator++(int);
/**
* Pre-decrement operator
* Iterator will advance one index towards the beginning.
1998-04-22 22:28:48 +04:00
*
* @return object_at(--index)
1998-04-22 22:28:48 +04:00
*/
void* operator--();
/**
* Post-decrement operator
* Iterator will advance one index towards the beginning.
1998-04-22 22:28:48 +04:00
*
* @param param is ignored
* @return object_at(index--)
1998-04-22 22:28:48 +04:00
*/
void* operator--(int);
1998-04-22 22:28:48 +04:00
/**
* Retrieve the the iterator's notion of current node.
*
* Note that the iterator floats, so you don't need to do:
* <code>++iter; aDeque.PopFront();</code>
* Unless you actually want your iterator to jump 2 positions
* relative to its origin.
*
* Picture: [1 2i 3 4]
* PopFront()
* Picture: [2 3i 4]
* Note that I still happily points to object at the second index.
1998-04-22 22:28:48 +04:00
*
* @return object at i'th index
1998-04-22 22:28:48 +04:00
*/
void* GetCurrent();
1998-04-22 22:28:48 +04:00
/**
* Call this method when you want to iterate all the
1998-04-22 22:28:48 +04:00
* members of the container, passing a functor along
* to call your code.
*
* @param aFunctor object to call for each member
* @return *this
*/
void ForEach(nsDequeFunctor& aFunctor) const;
1998-08-05 05:59:34 +04:00
/**
* Call this method when you want to iterate all the
* members of the container, calling the functor you
* passed with each member. This process will interrupt
* if your function returns non 0 to this method.
1998-08-05 05:59:34 +04:00
*
* @param aFunctor object to call for each member
* @return first nonzero result of aFunctor or 0.
1998-08-05 05:59:34 +04:00
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
1998-04-22 22:28:48 +04:00
protected:
1999-03-31 12:42:06 +04:00
int32_t mIndex;
const nsDeque& mDeque;
1998-04-22 22:28:48 +04:00
};
#endif