зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1337953 - Make nsDeque templated on pointer type r=froydnj
Differential Revision: https://phabricator.services.mozilla.com/D79629
This commit is contained in:
Родитель
a383fd6b63
Коммит
6f84249b41
|
@ -261,7 +261,7 @@ class EventSourceImpl final : public nsIObserver,
|
|||
// EventSourceImpl on target thread but should only be used on target thread.
|
||||
nsString mLastEventID;
|
||||
UniquePtr<Message> mCurrentMessage;
|
||||
nsDeque mMessagesToDispatch;
|
||||
nsDeque<Message> mMessagesToDispatch;
|
||||
ParserStatus mStatus;
|
||||
mozilla::UniquePtr<mozilla::Decoder> mUnicodeDecoder;
|
||||
nsString mLastFieldName;
|
||||
|
@ -457,7 +457,7 @@ void EventSourceImpl::CloseInternal() {
|
|||
}
|
||||
|
||||
while (mMessagesToDispatch.GetSize() != 0) {
|
||||
delete static_cast<Message*>(mMessagesToDispatch.PopFront());
|
||||
delete mMessagesToDispatch.PopFront();
|
||||
}
|
||||
SetFrozen(false);
|
||||
ResetDecoder();
|
||||
|
@ -1450,8 +1450,7 @@ void EventSourceImpl::DispatchAllMessageEvents() {
|
|||
JSContext* cx = jsapi.cx();
|
||||
|
||||
while (mMessagesToDispatch.GetSize() > 0) {
|
||||
UniquePtr<Message> message(
|
||||
static_cast<Message*>(mMessagesToDispatch.PopFront()));
|
||||
UniquePtr<Message> message(mMessagesToDispatch.PopFront());
|
||||
|
||||
if (message->mLastEventID.isSome()) {
|
||||
mLastEventID.Assign(message->mLastEventID.value());
|
||||
|
|
|
@ -886,7 +886,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
// Hash table to track coalesced mousemove events for different pointers.
|
||||
nsClassHashtable<nsUint32HashKey, CoalescedMouseData> mCoalescedMouseData;
|
||||
|
||||
nsDeque mToBeDispatchedMouseData;
|
||||
nsDeque<CoalescedMouseData> mToBeDispatchedMouseData;
|
||||
|
||||
CoalescedWheelData mCoalescedWheelData;
|
||||
RefPtr<CoalescedMouseMoveFlusher> mCoalescedMouseEventFlusher;
|
||||
|
|
|
@ -3951,28 +3951,28 @@ RefPtr<GenericPromise> MediaDecoderStateMachine::RequestDebugInfo(
|
|||
return p;
|
||||
}
|
||||
|
||||
class VideoQueueMemoryFunctor : public nsDequeFunctor {
|
||||
class VideoQueueMemoryFunctor : public nsDequeFunctor<VideoData> {
|
||||
public:
|
||||
VideoQueueMemoryFunctor() : mSize(0) {}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
|
||||
|
||||
virtual void operator()(void* aObject) override {
|
||||
const VideoData* v = static_cast<const VideoData*>(aObject);
|
||||
virtual void operator()(VideoData* aObject) override {
|
||||
const VideoData* v = aObject;
|
||||
mSize += v->SizeOfIncludingThis(MallocSizeOf);
|
||||
}
|
||||
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
class AudioQueueMemoryFunctor : public nsDequeFunctor {
|
||||
class AudioQueueMemoryFunctor : public nsDequeFunctor<AudioData> {
|
||||
public:
|
||||
AudioQueueMemoryFunctor() : mSize(0) {}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
|
||||
|
||||
virtual void operator()(void* aObject) override {
|
||||
const AudioData* audioData = static_cast<const AudioData*>(aObject);
|
||||
virtual void operator()(AudioData* aObject) override {
|
||||
const AudioData* audioData = aObject;
|
||||
mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,17 +21,17 @@ class AudioData;
|
|||
|
||||
// Thread and type safe wrapper around nsDeque.
|
||||
template <class T>
|
||||
class MediaQueueDeallocator : public nsDequeFunctor {
|
||||
virtual void operator()(void* aObject) override {
|
||||
RefPtr<T> releaseMe = dont_AddRef(static_cast<T*>(aObject));
|
||||
class MediaQueueDeallocator : public nsDequeFunctor<T> {
|
||||
virtual void operator()(T* aObject) override {
|
||||
RefPtr<T> releaseMe = dont_AddRef(aObject);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class MediaQueue : private nsDeque {
|
||||
class MediaQueue : private nsDeque<T> {
|
||||
public:
|
||||
MediaQueue()
|
||||
: nsDeque(new MediaQueueDeallocator<T>()),
|
||||
: nsDeque<T>(new MediaQueueDeallocator<T>()),
|
||||
mRecursiveMutex("mediaqueue"),
|
||||
mEndOfStream(false) {}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class MediaQueue : private nsDeque {
|
|||
|
||||
inline size_t GetSize() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return nsDeque::GetSize();
|
||||
return nsDeque<T>::GetSize();
|
||||
}
|
||||
|
||||
inline void Push(T* aItem) {
|
||||
|
@ -52,7 +52,7 @@ class MediaQueue : private nsDeque {
|
|||
T* item = aItem.take();
|
||||
MOZ_DIAGNOSTIC_ASSERT(item);
|
||||
MOZ_DIAGNOSTIC_ASSERT(item->GetEndTime() >= item->mTime);
|
||||
nsDeque::Push(item);
|
||||
nsDeque<T>::Push(item);
|
||||
mPushEvent.Notify(RefPtr<T>(item));
|
||||
// Pushing new data after queue has ended means that the stream is active
|
||||
// again, so we should not mark it as ended.
|
||||
|
@ -63,7 +63,7 @@ class MediaQueue : private nsDeque {
|
|||
|
||||
inline already_AddRefed<T> PopFront() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
RefPtr<T> rv = dont_AddRef(static_cast<T*>(nsDeque::PopFront()));
|
||||
RefPtr<T> rv = dont_AddRef(nsDeque<T>::PopFront());
|
||||
if (rv) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(rv->GetEndTime() >= rv->mTime);
|
||||
mPopFrontEvent.Notify(rv);
|
||||
|
@ -73,24 +73,24 @@ class MediaQueue : private nsDeque {
|
|||
|
||||
inline already_AddRefed<T> PopBack() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
RefPtr<T> rv = dont_AddRef(static_cast<T*>(nsDeque::Pop()));
|
||||
RefPtr<T> rv = dont_AddRef(nsDeque<T>::Pop());
|
||||
return rv.forget();
|
||||
}
|
||||
|
||||
inline RefPtr<T> PeekFront() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return static_cast<T*>(nsDeque::PeekFront());
|
||||
return nsDeque<T>::PeekFront();
|
||||
}
|
||||
|
||||
inline RefPtr<T> PeekBack() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return static_cast<T*>(nsDeque::Peek());
|
||||
return nsDeque<T>::Peek();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
while (GetSize() > 0) {
|
||||
RefPtr<T> x = dont_AddRef(static_cast<T*>(nsDeque::PopFront()));
|
||||
RefPtr<T> x = dont_AddRef(nsDeque<T>::PopFront());
|
||||
}
|
||||
mEndOfStream = false;
|
||||
}
|
||||
|
@ -123,14 +123,14 @@ class MediaQueue : private nsDeque {
|
|||
if (GetSize() == 0) {
|
||||
return 0;
|
||||
}
|
||||
T* last = static_cast<T*>(nsDeque::Peek());
|
||||
T* first = static_cast<T*>(nsDeque::PeekFront());
|
||||
T* last = nsDeque<T>::Peek();
|
||||
T* first = nsDeque<T>::PeekFront();
|
||||
return (last->GetEndTime() - first->mTime).ToMicroseconds();
|
||||
}
|
||||
|
||||
void LockedForEach(nsDequeFunctor& aFunctor) const {
|
||||
void LockedForEach(nsDequeFunctor<T>& aFunctor) const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
ForEach(aFunctor);
|
||||
nsDeque<T>::ForEach(aFunctor);
|
||||
}
|
||||
|
||||
// Extracts elements from the queue into aResult, in order.
|
||||
|
@ -140,13 +140,13 @@ class MediaQueue : private nsDeque {
|
|||
if (GetSize() == 0) return;
|
||||
size_t i;
|
||||
for (i = GetSize() - 1; i > 0; --i) {
|
||||
T* v = static_cast<T*>(ObjectAt(i));
|
||||
T* v = nsDeque<T>::ObjectAt(i);
|
||||
if (v->GetEndTime().ToMicroseconds() < aTime) break;
|
||||
}
|
||||
// Elements less than i have a end time before aTime. It's also possible
|
||||
// that the element at i has a end time before aTime, but that's OK.
|
||||
for (; i < GetSize(); ++i) {
|
||||
RefPtr<T> elem = static_cast<T*>(ObjectAt(static_cast<size_t>(i)));
|
||||
RefPtr<T> elem = nsDeque<T>::ObjectAt(i);
|
||||
aResult->AppendElement(elem);
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ class MediaQueue : private nsDeque {
|
|||
void GetFirstElements(uint32_t aMaxElements, nsTArray<RefPtr<T>>* aResult) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
for (size_t i = 0; i < aMaxElements && i < GetSize(); ++i) {
|
||||
*aResult->AppendElement() = static_cast<T*>(ObjectAt(i));
|
||||
*aResult->AppendElement() = nsDeque<T>::ObjectAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ class MediaQueue : private nsDeque {
|
|||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
uint32_t frames = 0;
|
||||
for (size_t i = 0; i < GetSize(); ++i) {
|
||||
T* v = static_cast<T*>(ObjectAt(i));
|
||||
T* v = nsDeque<T>::ObjectAt(i);
|
||||
frames += v->Frames();
|
||||
}
|
||||
return frames;
|
||||
|
|
|
@ -284,7 +284,7 @@ TEST(MultiWriterQueue, MultiWriterMultiReader)
|
|||
|
||||
// Single-threaded use only.
|
||||
struct DequeWrapperST {
|
||||
nsDeque mDQ;
|
||||
nsDeque<void> mDQ;
|
||||
|
||||
bool Push(int i) {
|
||||
mDQ.PushFront(reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
|
||||
|
|
|
@ -11,14 +11,13 @@ using mozilla::AudioData;
|
|||
using mozilla::AudioDataValue;
|
||||
using mozilla::MediaQueue;
|
||||
|
||||
class MemoryFunctor : public nsDequeFunctor {
|
||||
class MemoryFunctor : public nsDequeFunctor<AudioData> {
|
||||
public:
|
||||
MemoryFunctor() : mSize(0) {}
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
|
||||
|
||||
void operator()(void* aObject) override {
|
||||
const AudioData* audioData = static_cast<const AudioData*>(aObject);
|
||||
mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
|
||||
void operator()(AudioData* aObject) override {
|
||||
mSize += aObject->SizeOfIncludingThis(MallocSizeOf);
|
||||
}
|
||||
|
||||
size_t mSize;
|
||||
|
|
|
@ -31,14 +31,14 @@ size_t ResourceItem::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
|
|||
return aMallocSizeOf(this);
|
||||
}
|
||||
|
||||
class ResourceQueueDeallocator : public nsDequeFunctor {
|
||||
void operator()(void* aObject) override {
|
||||
delete static_cast<ResourceItem*>(aObject);
|
||||
}
|
||||
class ResourceQueueDeallocator : public nsDequeFunctor<ResourceItem> {
|
||||
void operator()(ResourceItem* aObject) override { delete aObject; }
|
||||
};
|
||||
|
||||
ResourceQueue::ResourceQueue()
|
||||
: nsDeque(new ResourceQueueDeallocator()), mLogicalLength(0), mOffset(0) {}
|
||||
: nsDeque<ResourceItem>(new ResourceQueueDeallocator()),
|
||||
mLogicalLength(0),
|
||||
mOffset(0) {}
|
||||
|
||||
uint64_t ResourceQueue::GetOffset() { return mOffset; }
|
||||
|
||||
|
@ -125,7 +125,7 @@ uint32_t ResourceQueue::EvictAll() {
|
|||
|
||||
size_t ResourceQueue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||
// Calculate the size of the internal deque.
|
||||
size_t size = nsDeque::SizeOfExcludingThis(aMallocSizeOf);
|
||||
size_t size = nsDeque<ResourceItem>::SizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
// Sum the ResourceItems. The ResourceItems's MediaSpans may share the
|
||||
// same underlying MediaByteBuffers, so we need to de-dupe the buffers
|
||||
|
@ -194,7 +194,7 @@ uint32_t ResourceQueue::GetAtOffset(uint64_t aOffset,
|
|||
}
|
||||
|
||||
ResourceItem* ResourceQueue::PopFront() {
|
||||
return static_cast<ResourceItem*>(nsDeque::PopFront());
|
||||
return nsDeque<ResourceItem>::PopFront();
|
||||
}
|
||||
|
||||
#undef SBR_DEBUG
|
||||
|
|
|
@ -32,7 +32,7 @@ struct ResourceItem {
|
|||
uint64_t mOffset;
|
||||
};
|
||||
|
||||
class ResourceQueue : private nsDeque {
|
||||
class ResourceQueue : private nsDeque<ResourceItem> {
|
||||
public:
|
||||
ResourceQueue();
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ struct OggPacketDeletePolicy {
|
|||
using OggPacketPtr = UniquePtr<ogg_packet, OggPacketDeletePolicy>;
|
||||
|
||||
// Deallocates a packet, used in OggPacketQueue below.
|
||||
class OggPacketDeallocator : public nsDequeFunctor {
|
||||
virtual void operator()(void* aPacket) override {
|
||||
OggPacketDeletePolicy()(static_cast<ogg_packet*>(aPacket));
|
||||
class OggPacketDeallocator : public nsDequeFunctor<ogg_packet> {
|
||||
virtual void operator()(ogg_packet* aPacket) override {
|
||||
OggPacketDeletePolicy()(aPacket);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -78,29 +78,25 @@ class OggPacketDeallocator : public nsDequeFunctor {
|
|||
// frames/samples, reducing the amount of frames/samples we must decode to
|
||||
// determine start-time at a particular offset, and gives us finer control
|
||||
// over memory usage.
|
||||
class OggPacketQueue : private nsDeque {
|
||||
class OggPacketQueue : private nsDeque<ogg_packet> {
|
||||
public:
|
||||
OggPacketQueue() : nsDeque(new OggPacketDeallocator()) {}
|
||||
~OggPacketQueue() { Erase(); }
|
||||
bool IsEmpty() { return nsDeque::GetSize() == 0; }
|
||||
bool IsEmpty() { return nsDeque<ogg_packet>::GetSize() == 0; }
|
||||
void Append(OggPacketPtr aPacket);
|
||||
OggPacketPtr PopFront() {
|
||||
return OggPacketPtr(static_cast<ogg_packet*>(nsDeque::PopFront()));
|
||||
}
|
||||
ogg_packet* PeekFront() {
|
||||
return static_cast<ogg_packet*>(nsDeque::PeekFront());
|
||||
}
|
||||
OggPacketPtr Pop() {
|
||||
return OggPacketPtr(static_cast<ogg_packet*>(nsDeque::Pop()));
|
||||
return OggPacketPtr(nsDeque<ogg_packet>::PopFront());
|
||||
}
|
||||
ogg_packet* PeekFront() { return nsDeque<ogg_packet>::PeekFront(); }
|
||||
OggPacketPtr Pop() { return OggPacketPtr(nsDeque<ogg_packet>::Pop()); }
|
||||
ogg_packet* operator[](size_t aIndex) const {
|
||||
return static_cast<ogg_packet*>(nsDeque::ObjectAt(aIndex));
|
||||
return nsDeque<ogg_packet>::ObjectAt(aIndex);
|
||||
}
|
||||
size_t Length() const { return nsDeque::GetSize(); }
|
||||
size_t Length() const { return nsDeque<ogg_packet>::GetSize(); }
|
||||
void PushFront(OggPacketPtr aPacket) {
|
||||
nsDeque::PushFront(aPacket.release());
|
||||
nsDeque<ogg_packet>::PushFront(aPacket.release());
|
||||
}
|
||||
void Erase() { nsDeque::Erase(); }
|
||||
void Erase() { nsDeque<ogg_packet>::Erase(); }
|
||||
};
|
||||
|
||||
// Encapsulates the data required for decoding an ogg bitstream and for
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class TransactionStackDeallocator final : public nsDequeFunctor {
|
||||
virtual void operator()(void* aObject) override {
|
||||
RefPtr<TransactionItem> releaseMe =
|
||||
dont_AddRef(static_cast<TransactionItem*>(aObject));
|
||||
class TransactionStackDeallocator final
|
||||
: public nsDequeFunctor<TransactionItem> {
|
||||
virtual void operator()(TransactionItem* aObject) override {
|
||||
RefPtr<TransactionItem> releaseMe = dont_AddRef(aObject);
|
||||
}
|
||||
};
|
||||
|
||||
TransactionStack::TransactionStack(Type aType)
|
||||
: nsDeque(new TransactionStackDeallocator()), mType(aType) {}
|
||||
: nsDeque<TransactionItem>(new TransactionStackDeallocator()),
|
||||
mType(aType) {}
|
||||
|
||||
TransactionStack::~TransactionStack() { Clear(); }
|
||||
|
||||
|
@ -42,33 +43,31 @@ void TransactionStack::Push(
|
|||
return;
|
||||
}
|
||||
|
||||
nsDeque::Push(transactionItem.forget().take());
|
||||
nsDeque<TransactionItem>::Push(transactionItem.forget().take());
|
||||
}
|
||||
|
||||
already_AddRefed<TransactionItem> TransactionStack::Pop() {
|
||||
RefPtr<TransactionItem> item =
|
||||
dont_AddRef(static_cast<TransactionItem*>(nsDeque::Pop()));
|
||||
RefPtr<TransactionItem> item = dont_AddRef(nsDeque<TransactionItem>::Pop());
|
||||
return item.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TransactionItem> TransactionStack::PopBottom() {
|
||||
RefPtr<TransactionItem> item =
|
||||
dont_AddRef(static_cast<TransactionItem*>(nsDeque::PopFront()));
|
||||
dont_AddRef(nsDeque<TransactionItem>::PopFront());
|
||||
return item.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TransactionItem> TransactionStack::Peek() {
|
||||
RefPtr<TransactionItem> item = static_cast<TransactionItem*>(nsDeque::Peek());
|
||||
RefPtr<TransactionItem> item = nsDeque<TransactionItem>::Peek();
|
||||
return item.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TransactionItem> TransactionStack::GetItemAt(
|
||||
size_t aIndex) const {
|
||||
if (NS_WARN_IF(aIndex >= nsDeque::GetSize())) {
|
||||
if (NS_WARN_IF(aIndex >= nsDeque<TransactionItem>::GetSize())) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<TransactionItem> item =
|
||||
static_cast<TransactionItem*>(nsDeque::ObjectAt(aIndex));
|
||||
RefPtr<TransactionItem> item = nsDeque<TransactionItem>::ObjectAt(aIndex);
|
||||
return item.forget();
|
||||
}
|
||||
|
||||
|
@ -81,7 +80,7 @@ void TransactionStack::Clear() {
|
|||
void TransactionStack::DoTraverse(nsCycleCollectionTraversalCallback& cb) {
|
||||
size_t size = GetSize();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
TransactionItem* item = static_cast<TransactionItem*>(nsDeque::ObjectAt(i));
|
||||
TransactionItem* item = nsDeque<TransactionItem>::ObjectAt(i);
|
||||
if (item) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "transaction stack mDeque[i]");
|
||||
cb.NoteNativeChild(item,
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace mozilla {
|
|||
|
||||
class TransactionItem;
|
||||
|
||||
class TransactionStack : private nsDeque {
|
||||
class TransactionStack : private nsDeque<TransactionItem> {
|
||||
public:
|
||||
enum Type { FOR_UNDO, FOR_REDO };
|
||||
|
||||
|
|
|
@ -104,8 +104,7 @@ EventTokenBucket::~EventTokenBucket() {
|
|||
|
||||
// Complete any queued events to prevent hangs
|
||||
while (mEvents.GetSize()) {
|
||||
RefPtr<TokenBucketCancelable> cancelable =
|
||||
dont_AddRef(static_cast<TokenBucketCancelable*>(mEvents.PopFront()));
|
||||
RefPtr<TokenBucketCancelable> cancelable = dont_AddRef(mEvents.PopFront());
|
||||
cancelable->Fire();
|
||||
}
|
||||
}
|
||||
|
@ -197,8 +196,7 @@ void EventTokenBucket::Stop() {
|
|||
|
||||
// Complete any queued events to prevent hangs
|
||||
while (mEvents.GetSize()) {
|
||||
RefPtr<TokenBucketCancelable> cancelable =
|
||||
dont_AddRef(static_cast<TokenBucketCancelable*>(mEvents.PopFront()));
|
||||
RefPtr<TokenBucketCancelable> cancelable = dont_AddRef(mEvents.PopFront());
|
||||
cancelable->Fire();
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +242,7 @@ void EventTokenBucket::DispatchEvents() {
|
|||
if (mPaused || mStopped) return;
|
||||
|
||||
while (mEvents.GetSize() && mUnitCost <= mCredit) {
|
||||
RefPtr<TokenBucketCancelable> cancelable =
|
||||
dont_AddRef(static_cast<TokenBucketCancelable*>(mEvents.PopFront()));
|
||||
RefPtr<TokenBucketCancelable> cancelable = dont_AddRef(mEvents.PopFront());
|
||||
if (cancelable->mEvent) {
|
||||
SOCKET_LOG(
|
||||
("EventTokenBucket::DispachEvents [%p] "
|
||||
|
|
|
@ -121,7 +121,7 @@ class EventTokenBucket : public nsITimerCallback,
|
|||
|
||||
bool mPaused;
|
||||
bool mStopped;
|
||||
nsDeque mEvents;
|
||||
nsDeque<TokenBucketCancelable> mEvents;
|
||||
bool mTimerArmed;
|
||||
TimeStamp mLastUpdate;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ static nsDataHashtable<nsPtrHashKey<PRFileDesc>, NetworkFuzzingBuffer*>
|
|||
gConnectedNetworkFuzzingBuffers;
|
||||
|
||||
// This holds all buffers for connections we can still open.
|
||||
static nsDeque gNetworkFuzzingBuffers;
|
||||
static nsDeque<NetworkFuzzingBuffer> gNetworkFuzzingBuffers;
|
||||
|
||||
// This is `true` once all connections are closed and either there are
|
||||
// no buffers left to be used or all remaining buffers are marked optional.
|
||||
|
@ -143,8 +143,7 @@ static PRStatus FuzzyConnect(PRFileDesc* fd, const PRNetAddr* addr,
|
|||
|
||||
MutexAutoLock lock(gConnRecvMutex);
|
||||
|
||||
NetworkFuzzingBuffer* buf =
|
||||
(NetworkFuzzingBuffer*)gNetworkFuzzingBuffers.PopFront();
|
||||
NetworkFuzzingBuffer* buf = gNetworkFuzzingBuffers.PopFront();
|
||||
if (!buf) {
|
||||
FUZZING_LOG(("[FuzzyConnect] Denying additional connection."));
|
||||
return PR_FAILURE;
|
||||
|
@ -266,8 +265,7 @@ static PRStatus FuzzyClose(PRFileDesc* fd) {
|
|||
// unused network buffers that were not marked as optional.
|
||||
bool haveRemainingUnusedBuffers = false;
|
||||
for (size_t i = 0; i < gNetworkFuzzingBuffers.GetSize(); ++i) {
|
||||
NetworkFuzzingBuffer* buf = static_cast<NetworkFuzzingBuffer*>(
|
||||
gNetworkFuzzingBuffers.ObjectAt(i));
|
||||
NetworkFuzzingBuffer* buf = gNetworkFuzzingBuffers.ObjectAt(i);
|
||||
|
||||
if (!buf->allowUnused) {
|
||||
haveRemainingUnusedBuffers = true;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
static nsDeque* gStaticHeaders = nullptr;
|
||||
static nsDeque<nvPair>* gStaticHeaders = nullptr;
|
||||
|
||||
class HpackStaticTableReporter final : public nsIMemoryReporter {
|
||||
public:
|
||||
|
@ -104,7 +104,7 @@ static void AddStaticElement(const nsCString& name) {
|
|||
static void InitializeStaticHeaders() {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
if (!gStaticHeaders) {
|
||||
gStaticHeaders = new nsDeque();
|
||||
gStaticHeaders = new nsDeque<nvPair>();
|
||||
gStaticReporter = new HpackStaticTableReporter();
|
||||
RegisterStrongMemoryReporter(gStaticReporter);
|
||||
AddStaticElement(NS_LITERAL_CSTRING(":authority"));
|
||||
|
@ -198,7 +198,7 @@ void nvFIFO::AddElement(const nsCString& name) {
|
|||
}
|
||||
|
||||
void nvFIFO::RemoveElement() {
|
||||
nvPair* pair = static_cast<nvPair*>(mTable.Pop());
|
||||
nvPair* pair = mTable.Pop();
|
||||
if (pair) {
|
||||
mByteCount -= pair->Size();
|
||||
delete pair;
|
||||
|
@ -217,7 +217,9 @@ size_t nvFIFO::StaticLength() const { return gStaticHeaders->GetSize(); }
|
|||
|
||||
void nvFIFO::Clear() {
|
||||
mByteCount = 0;
|
||||
while (mTable.GetSize()) delete static_cast<nvPair*>(mTable.Pop());
|
||||
while (mTable.GetSize()) {
|
||||
delete mTable.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
const nvPair* nvFIFO::operator[](size_t index) const {
|
||||
|
@ -229,10 +231,9 @@ const nvPair* nvFIFO::operator[](size_t index) const {
|
|||
return nullptr;
|
||||
}
|
||||
if (index >= gStaticHeaders->GetSize()) {
|
||||
return static_cast<nvPair*>(
|
||||
mTable.ObjectAt(index - gStaticHeaders->GetSize()));
|
||||
return mTable.ObjectAt(index - gStaticHeaders->GetSize());
|
||||
}
|
||||
return static_cast<nvPair*>(gStaticHeaders->ObjectAt(index));
|
||||
return gStaticHeaders->ObjectAt(index);
|
||||
}
|
||||
|
||||
Http2BaseCompressor::Http2BaseCompressor()
|
||||
|
|
|
@ -50,7 +50,7 @@ class nvFIFO {
|
|||
|
||||
private:
|
||||
uint32_t mByteCount;
|
||||
nsDeque mTable;
|
||||
nsDeque<nvPair> mTable;
|
||||
};
|
||||
|
||||
class HpackDynamicTableReporter;
|
||||
|
|
|
@ -587,8 +587,7 @@ void Http2Session::QueueStream(Http2Stream* stream) {
|
|||
#ifdef DEBUG
|
||||
int32_t qsize = mQueuedStreams.GetSize();
|
||||
for (int32_t i = 0; i < qsize; i++) {
|
||||
Http2Stream* qStream =
|
||||
static_cast<Http2Stream*>(mQueuedStreams.ObjectAt(i));
|
||||
Http2Stream* qStream = mQueuedStreams.ObjectAt(i);
|
||||
MOZ_ASSERT(qStream != stream);
|
||||
MOZ_ASSERT(qStream->Queued());
|
||||
}
|
||||
|
@ -602,8 +601,7 @@ void Http2Session::ProcessPending() {
|
|||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
Http2Stream* stream;
|
||||
while (RoomForMoreConcurrent() &&
|
||||
(stream = static_cast<Http2Stream*>(mQueuedStreams.PopFront()))) {
|
||||
while (RoomForMoreConcurrent() && (stream = mQueuedStreams.PopFront())) {
|
||||
LOG3(("Http2Session::ProcessPending %p stream %p woken from queue.", this,
|
||||
stream));
|
||||
MOZ_ASSERT(!stream->CountAsActive());
|
||||
|
@ -1270,10 +1268,11 @@ void Http2Session::CleanupStream(uint32_t aID, nsresult aResult,
|
|||
CleanupStream(stream, aResult, aResetCode);
|
||||
}
|
||||
|
||||
static void RemoveStreamFromQueue(Http2Stream* aStream, nsDeque& queue) {
|
||||
static void RemoveStreamFromQueue(Http2Stream* aStream,
|
||||
nsDeque<Http2Stream>& queue) {
|
||||
size_t size = queue.GetSize();
|
||||
for (size_t count = 0; count < size; ++count) {
|
||||
Http2Stream* stream = static_cast<Http2Stream*>(queue.PopFront());
|
||||
Http2Stream* stream = queue.PopFront();
|
||||
if (stream != aStream) queue.Push(stream);
|
||||
}
|
||||
}
|
||||
|
@ -2179,8 +2178,7 @@ nsresult Http2Session::RecvGoAway(Http2Session* self) {
|
|||
// are not covered by the last-good id.
|
||||
size = self->mQueuedStreams.GetSize();
|
||||
for (size_t count = 0; count < size; ++count) {
|
||||
Http2Stream* stream =
|
||||
static_cast<Http2Stream*>(self->mQueuedStreams.PopFront());
|
||||
Http2Stream* stream = self->mQueuedStreams.PopFront();
|
||||
MOZ_ASSERT(stream->Queued());
|
||||
stream->SetQueued(false);
|
||||
if (self->mPeerGoAwayReason == HTTP_1_1_REQUIRED) {
|
||||
|
@ -2763,7 +2761,7 @@ nsresult Http2Session::ReadSegmentsAgain(nsAHttpSegmentReader* reader,
|
|||
|
||||
LOG3(("Http2Session::ReadSegments %p", this));
|
||||
|
||||
Http2Stream* stream = static_cast<Http2Stream*>(mReadyForWrite.PopFront());
|
||||
Http2Stream* stream = mReadyForWrite.PopFront();
|
||||
if (!stream) {
|
||||
LOG3(("Http2Session %p could not identify a stream to write; suspending.",
|
||||
this));
|
||||
|
@ -3002,8 +3000,7 @@ nsresult Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter* writer,
|
|||
// If there are http transactions attached to a push stream with filled
|
||||
// buffers trigger that data pump here. This only reads from buffers (not the
|
||||
// network) so mDownstreamState doesn't matter.
|
||||
Http2Stream* pushConnectedStream =
|
||||
static_cast<Http2Stream*>(mPushesReadyForRead.PopFront());
|
||||
Http2Stream* pushConnectedStream = mPushesReadyForRead.PopFront();
|
||||
if (pushConnectedStream) {
|
||||
return ProcessConnectedPush(pushConnectedStream, writer, count,
|
||||
countWritten);
|
||||
|
@ -3011,8 +3008,7 @@ nsresult Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter* writer,
|
|||
|
||||
// feed gecko channels that previously stopped consuming data
|
||||
// only take data from stored buffers
|
||||
Http2Stream* slowConsumer =
|
||||
static_cast<Http2Stream*>(mSlowConsumersReadyForRead.PopFront());
|
||||
Http2Stream* slowConsumer = mSlowConsumersReadyForRead.PopFront();
|
||||
if (slowConsumer) {
|
||||
internalStateType savedState = mDownstreamState;
|
||||
mDownstreamState = NOT_USING_NETWORK;
|
||||
|
|
|
@ -381,10 +381,10 @@ class Http2Session final : public ASpdySession,
|
|||
nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>, Http2Stream>
|
||||
mStreamTransactionHash;
|
||||
|
||||
nsDeque mReadyForWrite;
|
||||
nsDeque mQueuedStreams;
|
||||
nsDeque mPushesReadyForRead;
|
||||
nsDeque mSlowConsumersReadyForRead;
|
||||
nsDeque<Http2Stream> mReadyForWrite;
|
||||
nsDeque<Http2Stream> mQueuedStreams;
|
||||
nsDeque<Http2Stream> mPushesReadyForRead;
|
||||
nsDeque<Http2Stream> mSlowConsumersReadyForRead;
|
||||
nsTArray<Http2PushedStream*> mPushedStreams;
|
||||
|
||||
// Compression contexts for header transport.
|
||||
|
@ -527,7 +527,7 @@ class Http2Session final : public ASpdySession,
|
|||
bool mPreviousUsed; // true when backup is used
|
||||
|
||||
// used as a temporary buffer while enumerating the stream hash during GoAway
|
||||
nsDeque mGoAwayStreamsToRestart;
|
||||
nsDeque<Http2Stream> mGoAwayStreamsToRestart;
|
||||
|
||||
// Each session gets a unique serial number because the push cache is
|
||||
// correlated by the load group and the serial number can be used as part of
|
||||
|
|
|
@ -571,7 +571,7 @@ void Http3Session::ProcessPending() {
|
|||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
Http3Stream* stream;
|
||||
while ((stream = static_cast<Http3Stream*>(mQueuedStreams.PopFront()))) {
|
||||
while ((stream = mQueuedStreams.PopFront())) {
|
||||
LOG3(("Http3Session::ProcessPending %p stream %p woken from queue.", this,
|
||||
stream));
|
||||
MOZ_ASSERT(stream->Queued());
|
||||
|
@ -583,10 +583,11 @@ void Http3Session::ProcessPending() {
|
|||
}
|
||||
}
|
||||
|
||||
static void RemoveStreamFromQueue(Http3Stream* aStream, nsDeque& queue) {
|
||||
static void RemoveStreamFromQueue(Http3Stream* aStream,
|
||||
nsDeque<Http3Stream>& queue) {
|
||||
size_t size = queue.GetSize();
|
||||
for (size_t count = 0; count < size; ++count) {
|
||||
Http3Stream* stream = static_cast<Http3Stream*>(queue.PopFront());
|
||||
Http3Stream* stream = queue.PopFront();
|
||||
if (stream != aStream) {
|
||||
queue.Push(stream);
|
||||
}
|
||||
|
@ -759,7 +760,7 @@ nsresult Http3Session::ReadSegmentsAgain(nsAHttpSegmentReader* reader,
|
|||
while (
|
||||
(mState ==
|
||||
CONNECTED) && // Do not send transaction data untill we are connected.
|
||||
(stream = static_cast<Http3Stream*>(mReadyForWrite.PopFront()))) {
|
||||
(stream = mReadyForWrite.PopFront())) {
|
||||
LOG(
|
||||
("Http3Session::ReadSegmentsAgain call ReadSegments from stream=%p "
|
||||
"[this=%p]",
|
||||
|
|
|
@ -143,10 +143,10 @@ class Http3Session final : public nsAHttpTransaction,
|
|||
nsRefPtrHashtable<nsPtrHashKey<nsAHttpTransaction>, Http3Stream>
|
||||
mStreamTransactionHash;
|
||||
|
||||
nsDeque mReadyForWrite;
|
||||
nsDeque<Http3Stream> mReadyForWrite;
|
||||
nsTArray<uint64_t> mReadyForWriteButBlocked;
|
||||
nsTArray<RefPtr<Http3Stream>> mSlowConsumersReadyForRead;
|
||||
nsDeque mQueuedStreams;
|
||||
nsDeque<Http3Stream> mQueuedStreams;
|
||||
|
||||
enum State { INITIALIZING, CONNECTED, CLOSING, CLOSED } mState;
|
||||
|
||||
|
|
|
@ -1162,12 +1162,15 @@ WebSocketChannel::~WebSocketChannel() {
|
|||
free(mDynamicOutput);
|
||||
delete mCurrentOut;
|
||||
|
||||
while ((mCurrentOut = (OutboundMessage*)mOutgoingPingMessages.PopFront()))
|
||||
while ((mCurrentOut = mOutgoingPingMessages.PopFront())) {
|
||||
delete mCurrentOut;
|
||||
while ((mCurrentOut = (OutboundMessage*)mOutgoingPongMessages.PopFront()))
|
||||
}
|
||||
while ((mCurrentOut = mOutgoingPongMessages.PopFront())) {
|
||||
delete mCurrentOut;
|
||||
while ((mCurrentOut = (OutboundMessage*)mOutgoingMessages.PopFront()))
|
||||
}
|
||||
while ((mCurrentOut = mOutgoingMessages.PopFront())) {
|
||||
delete mCurrentOut;
|
||||
}
|
||||
|
||||
mListenerMT = nullptr;
|
||||
|
||||
|
@ -1885,7 +1888,7 @@ void WebSocketChannel::GeneratePong(uint8_t* payload, uint32_t len) {
|
|||
new OutboundMessage(kMsgTypePong, buf));
|
||||
}
|
||||
|
||||
void WebSocketChannel::EnqueueOutgoingMessage(nsDeque& aQueue,
|
||||
void WebSocketChannel::EnqueueOutgoingMessage(nsDeque<OutboundMessage>& aQueue,
|
||||
OutboundMessage* aMsg) {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
|
@ -1921,16 +1924,16 @@ void WebSocketChannel::PrimeNewOutgoingMessage() {
|
|||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mCurrentOut = (OutboundMessage*)mOutgoingPongMessages.PopFront();
|
||||
mCurrentOut = mOutgoingPongMessages.PopFront();
|
||||
if (mCurrentOut) {
|
||||
MOZ_ASSERT(mCurrentOut->GetMsgType() == kMsgTypePong, "Not pong message!");
|
||||
} else {
|
||||
mCurrentOut = (OutboundMessage*)mOutgoingPingMessages.PopFront();
|
||||
mCurrentOut = mOutgoingPingMessages.PopFront();
|
||||
if (mCurrentOut)
|
||||
MOZ_ASSERT(mCurrentOut->GetMsgType() == kMsgTypePing,
|
||||
"Not ping message!");
|
||||
else
|
||||
mCurrentOut = (OutboundMessage*)mOutgoingMessages.PopFront();
|
||||
mCurrentOut = mOutgoingMessages.PopFront();
|
||||
}
|
||||
|
||||
if (!mCurrentOut) return;
|
||||
|
|
|
@ -140,7 +140,8 @@ class WebSocketChannel : public BaseWebSocketChannel,
|
|||
uint32_t length,
|
||||
nsIInputStream* aStream = nullptr);
|
||||
|
||||
void EnqueueOutgoingMessage(nsDeque& aQueue, OutboundMessage* aMsg);
|
||||
void EnqueueOutgoingMessage(nsDeque<OutboundMessage>& aQueue,
|
||||
OutboundMessage* aMsg);
|
||||
|
||||
void PrimeNewOutgoingMessage();
|
||||
void DeleteCurrentOutGoingMessage();
|
||||
|
@ -284,9 +285,9 @@ class WebSocketChannel : public BaseWebSocketChannel,
|
|||
|
||||
OutboundMessage* mCurrentOut;
|
||||
uint32_t mCurrentOutSent;
|
||||
nsDeque mOutgoingMessages;
|
||||
nsDeque mOutgoingPingMessages;
|
||||
nsDeque mOutgoingPongMessages;
|
||||
nsDeque<OutboundMessage> mOutgoingMessages;
|
||||
nsDeque<OutboundMessage> mOutgoingPingMessages;
|
||||
nsDeque<OutboundMessage> mOutgoingPongMessages;
|
||||
uint32_t mHdrOutToSend;
|
||||
uint8_t* mHdrOut;
|
||||
uint8_t mOutHeader[kCopyBreak + 16];
|
||||
|
|
|
@ -904,18 +904,16 @@ void DataChannelConnection::ProcessQueuedOpens() {
|
|||
|
||||
// Can't copy nsDeque's. Move into temp array since any that fail will
|
||||
// go back to mPending
|
||||
nsDeque temp;
|
||||
nsDeque<DataChannel> temp;
|
||||
DataChannel* temp_channel; // really already_AddRefed<>
|
||||
while (nullptr !=
|
||||
(temp_channel = static_cast<DataChannel*>(mPending.PopFront()))) {
|
||||
temp.Push(static_cast<void*>(temp_channel));
|
||||
while (nullptr != (temp_channel = mPending.PopFront())) {
|
||||
temp.Push(temp_channel);
|
||||
}
|
||||
|
||||
RefPtr<DataChannel> channel;
|
||||
// All these entries have an AddRef(); make that explicit now via the
|
||||
// dont_AddRef()
|
||||
while (nullptr !=
|
||||
(channel = dont_AddRef(static_cast<DataChannel*>(temp.PopFront())))) {
|
||||
while (nullptr != (channel = dont_AddRef(temp.PopFront()))) {
|
||||
if (channel->mFlags & DATA_CHANNEL_FLAGS_FINISH_OPEN) {
|
||||
DC_DEBUG(("Processing queued open for %p (%u)", channel.get(),
|
||||
channel->mStream));
|
||||
|
@ -3057,8 +3055,7 @@ void DataChannelConnection::CloseAll() {
|
|||
|
||||
// Clean up any pending opens for channels
|
||||
RefPtr<DataChannel> channel;
|
||||
while (nullptr != (channel = dont_AddRef(
|
||||
static_cast<DataChannel*>(mPending.PopFront())))) {
|
||||
while (nullptr != (channel = dont_AddRef(mPending.PopFront()))) {
|
||||
DC_DEBUG(("closing pending channel %p, stream %u", channel.get(),
|
||||
channel->mStream));
|
||||
channel->Close(); // also releases the ref on each iteration
|
||||
|
|
|
@ -360,7 +360,7 @@ class DataChannelConnection final : public net::NeckoTargetHolder
|
|||
Channels mChannels;
|
||||
// STS only
|
||||
uint32_t mCurrentStream = 0;
|
||||
nsDeque mPending; // Holds addref'ed DataChannel's -- careful!
|
||||
nsDeque<DataChannel> mPending; // Holds addref'ed DataChannel's -- careful!
|
||||
// STS and main
|
||||
size_t mNegotiatedIdLimit = 0; // GUARDED_BY(mConnection->mLock)
|
||||
uint8_t mPendingType = PENDING_NONE;
|
||||
|
|
|
@ -172,12 +172,9 @@ typedef nsClassHashtable<nsCStringHashKey, BFSTableData> BFSHashTable;
|
|||
|
||||
// nsObjectHashtable enumerator functions.
|
||||
|
||||
class CStreamConvDeallocator : public nsDequeFunctor {
|
||||
class CStreamConvDeallocator : public nsDequeFunctor<nsCString> {
|
||||
public:
|
||||
void operator()(void* anObject) override {
|
||||
nsCString* string = (nsCString*)anObject;
|
||||
delete string;
|
||||
}
|
||||
void operator()(nsCString* anObject) override { delete anObject; }
|
||||
};
|
||||
|
||||
// walks the graph using a breadth-first-search algorithm which generates a
|
||||
|
|
|
@ -1221,9 +1221,9 @@ class GraphWalker {
|
|||
private:
|
||||
Visitor mVisitor;
|
||||
|
||||
void DoWalk(nsDeque& aQueue);
|
||||
void DoWalk(nsDeque<PtrInfo>& aQueue);
|
||||
|
||||
void CheckedPush(nsDeque& aQueue, PtrInfo* aPi) {
|
||||
void CheckedPush(nsDeque<PtrInfo>& aQueue, PtrInfo* aPi) {
|
||||
if (!aPi) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -1280,14 +1280,14 @@ static void ToParticipant(void* aParti, nsCycleCollectionParticipant** aCp) {
|
|||
|
||||
template <class Visitor>
|
||||
MOZ_NEVER_INLINE void GraphWalker<Visitor>::Walk(PtrInfo* aPi) {
|
||||
nsDeque queue;
|
||||
nsDeque<PtrInfo> queue;
|
||||
CheckedPush(queue, aPi);
|
||||
DoWalk(queue);
|
||||
}
|
||||
|
||||
template <class Visitor>
|
||||
MOZ_NEVER_INLINE void GraphWalker<Visitor>::WalkFromRoots(CCGraph& aGraph) {
|
||||
nsDeque queue;
|
||||
nsDeque<PtrInfo> queue;
|
||||
NodePool::Enumerator etor(aGraph.mNodes);
|
||||
for (uint32_t i = 0; i < aGraph.mRootCount; ++i) {
|
||||
CheckedPush(queue, etor.GetNext());
|
||||
|
@ -1296,11 +1296,11 @@ MOZ_NEVER_INLINE void GraphWalker<Visitor>::WalkFromRoots(CCGraph& aGraph) {
|
|||
}
|
||||
|
||||
template <class Visitor>
|
||||
MOZ_NEVER_INLINE void GraphWalker<Visitor>::DoWalk(nsDeque& aQueue) {
|
||||
MOZ_NEVER_INLINE void GraphWalker<Visitor>::DoWalk(nsDeque<PtrInfo>& aQueue) {
|
||||
// Use a aQueue to match the breadth-first traversal used when we
|
||||
// built the graph, for hopefully-better locality.
|
||||
while (aQueue.GetSize() > 0) {
|
||||
PtrInfo* pi = static_cast<PtrInfo*>(aQueue.PopFront());
|
||||
PtrInfo* pi = aQueue.PopFront();
|
||||
|
||||
if (pi->WasTraversed() && mVisitor.ShouldVisitNode(pi)) {
|
||||
mVisitor.VisitNode(pi);
|
||||
|
|
|
@ -12,13 +12,15 @@
|
|||
|
||||
#define modulus(x, y) ((x) % (y))
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Standard constructor
|
||||
* @param deallocator, called by Erase and ~nsDeque
|
||||
* @param deallocator, called by Erase and ~nsDequeBase
|
||||
*/
|
||||
nsDeque::nsDeque(nsDequeFunctor* aDeallocator) {
|
||||
MOZ_COUNT_CTOR(nsDeque);
|
||||
mDeallocator = aDeallocator;
|
||||
nsDequeBase::nsDequeBase() {
|
||||
MOZ_COUNT_CTOR(nsDequeBase);
|
||||
mOrigin = mSize = 0;
|
||||
mData = mBuffer; // don't allocate space until you must
|
||||
mCapacity = sizeof(mBuffer) / sizeof(mBuffer[0]);
|
||||
|
@ -28,49 +30,29 @@ nsDeque::nsDeque(nsDequeFunctor* aDeallocator) {
|
|||
/**
|
||||
* Destructor
|
||||
*/
|
||||
nsDeque::~nsDeque() {
|
||||
MOZ_COUNT_DTOR(nsDeque);
|
||||
nsDequeBase::~nsDequeBase() {
|
||||
MOZ_COUNT_DTOR(nsDequeBase);
|
||||
|
||||
Erase();
|
||||
if (mData && mData != mBuffer) {
|
||||
free(mData);
|
||||
}
|
||||
mData = 0;
|
||||
SetDeallocator(0);
|
||||
mData = nullptr;
|
||||
}
|
||||
|
||||
size_t nsDeque::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t nsDequeBase::SizeOfExcludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t size = 0;
|
||||
if (mData != mBuffer) {
|
||||
size += aMallocSizeOf(mData);
|
||||
}
|
||||
|
||||
if (mDeallocator) {
|
||||
size += aMallocSizeOf(mDeallocator);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t nsDeque::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the functor to be called by Erase()
|
||||
* The deque owns the functor.
|
||||
*
|
||||
* @param aDeallocator functor object for use by Erase()
|
||||
*/
|
||||
void nsDeque::SetDeallocator(nsDequeFunctor* aDeallocator) {
|
||||
delete mDeallocator;
|
||||
mDeallocator = aDeallocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from container without destroying them.
|
||||
*/
|
||||
void nsDeque::Empty() {
|
||||
void nsDequeBase::Empty() {
|
||||
if (mSize && mData) {
|
||||
memset(mData, 0, mCapacity * sizeof(*mData));
|
||||
}
|
||||
|
@ -78,16 +60,6 @@ void nsDeque::Empty() {
|
|||
mOrigin = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and delete all items from container
|
||||
*/
|
||||
void nsDeque::Erase() {
|
||||
if (mDeallocator && mSize) {
|
||||
ForEach(*mDeallocator);
|
||||
}
|
||||
Empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method quadruples the size of the deque
|
||||
* Elements in the deque are resequenced so that elements
|
||||
|
@ -95,7 +67,7 @@ void nsDeque::Erase() {
|
|||
*
|
||||
* @return whether growing succeeded
|
||||
*/
|
||||
bool nsDeque::GrowCapacity() {
|
||||
bool nsDequeBase::GrowCapacity() {
|
||||
mozilla::CheckedInt<size_t> newCapacity = mCapacity;
|
||||
newCapacity *= 4;
|
||||
|
||||
|
@ -144,7 +116,7 @@ bool nsDeque::GrowCapacity() {
|
|||
*
|
||||
* @param aItem: new item to be added to deque
|
||||
*/
|
||||
bool nsDeque::Push(void* aItem, const fallible_t&) {
|
||||
bool nsDequeBase::Push(void* aItem, const fallible_t&) {
|
||||
if (mSize == mCapacity && !GrowCapacity()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -185,7 +157,7 @@ bool nsDeque::Push(void* aItem, const fallible_t&) {
|
|||
* --
|
||||
* @param aItem: new item to be added to deque
|
||||
*/
|
||||
bool nsDeque::PushFront(void* aItem, const fallible_t&) {
|
||||
bool nsDequeBase::PushFront(void* aItem, const fallible_t&) {
|
||||
if (mOrigin == 0) {
|
||||
mOrigin = mCapacity - 1;
|
||||
} else {
|
||||
|
@ -209,13 +181,13 @@ bool nsDeque::PushFront(void* aItem, const fallible_t&) {
|
|||
*
|
||||
* @return ptr to last item in container
|
||||
*/
|
||||
void* nsDeque::Pop() {
|
||||
void* result = 0;
|
||||
void* nsDequeBase::Pop() {
|
||||
void* result = nullptr;
|
||||
if (mSize > 0) {
|
||||
--mSize;
|
||||
size_t offset = modulus(mSize + mOrigin, mCapacity);
|
||||
result = mData[offset];
|
||||
mData[offset] = 0;
|
||||
mData[offset] = nullptr;
|
||||
if (!mSize) {
|
||||
mOrigin = 0;
|
||||
}
|
||||
|
@ -229,12 +201,12 @@ void* nsDeque::Pop() {
|
|||
*
|
||||
* @return last item in container
|
||||
*/
|
||||
void* nsDeque::PopFront() {
|
||||
void* result = 0;
|
||||
void* nsDequeBase::PopFront() {
|
||||
void* result = nullptr;
|
||||
if (mSize > 0) {
|
||||
NS_ASSERTION(mOrigin < mCapacity, "Error: Bad origin");
|
||||
result = mData[mOrigin];
|
||||
mData[mOrigin++] = 0; // zero it out for debugging purposes.
|
||||
mData[mOrigin++] = nullptr; // zero it out for debugging purposes.
|
||||
mSize--;
|
||||
// Cycle around if we pop off the end
|
||||
// and reset origin if when we pop the last element
|
||||
|
@ -251,8 +223,8 @@ void* nsDeque::PopFront() {
|
|||
*
|
||||
* @return last item in container
|
||||
*/
|
||||
void* nsDeque::Peek() const {
|
||||
void* result = 0;
|
||||
void* nsDequeBase::Peek() const {
|
||||
void* result = nullptr;
|
||||
if (mSize > 0) {
|
||||
result = mData[modulus(mSize - 1 + mOrigin, mCapacity)];
|
||||
}
|
||||
|
@ -265,8 +237,8 @@ void* nsDeque::Peek() const {
|
|||
*
|
||||
* @return last item in container
|
||||
*/
|
||||
void* nsDeque::PeekFront() const {
|
||||
void* result = 0;
|
||||
void* nsDequeBase::PeekFront() const {
|
||||
void* result = nullptr;
|
||||
if (mSize > 0) {
|
||||
result = mData[mOrigin];
|
||||
}
|
||||
|
@ -282,24 +254,12 @@ void* nsDeque::PeekFront() const {
|
|||
* @param aIndex : 0 relative offset of item you want
|
||||
* @return void* or null
|
||||
*/
|
||||
void* nsDeque::ObjectAt(size_t aIndex) const {
|
||||
void* result = 0;
|
||||
void* nsDequeBase::ObjectAt(size_t aIndex) const {
|
||||
void* result = nullptr;
|
||||
if (aIndex < mSize) {
|
||||
result = mData[modulus(mOrigin + aIndex, mCapacity)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you want to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
void nsDeque::ForEach(nsDequeFunctor& aFunctor) const {
|
||||
for (size_t i = 0; i < mSize; ++i) {
|
||||
aFunctor(ObjectAt(i));
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* MODULE NOTES:
|
||||
*
|
||||
* The Deque is a very small, very efficient container object
|
||||
* than can hold items of type void*, offering the following features:
|
||||
* than can hold items of type T*, offering the following features:
|
||||
* - Its interface supports pushing, popping, and peeking of items at the back
|
||||
* or front, and retrieval from any position.
|
||||
* - It can iterate over items via a ForEach method, range-for, or an iterator
|
||||
|
@ -31,21 +31,9 @@
|
|||
#include "mozilla/fallible.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
/**
|
||||
* The nsDequeFunctor class is used when you want to create
|
||||
* callbacks between the deque and your generic code.
|
||||
* Use these objects in a call to ForEach(), and as custom deallocators.
|
||||
*/
|
||||
class nsDequeFunctor {
|
||||
public:
|
||||
virtual void operator()(void* aObject) = 0;
|
||||
virtual ~nsDequeFunctor() = default;
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Here comes the nsDeque class itself...
|
||||
******************************************************/
|
||||
namespace mozilla {
|
||||
|
||||
namespace detail {
|
||||
/**
|
||||
* The deque (double-ended queue) class is a common container type,
|
||||
* whose behavior mimics a line in your favorite checkout stand.
|
||||
|
@ -53,27 +41,11 @@ class nsDequeFunctor {
|
|||
* A deque allows insertion and removal at both ends of
|
||||
* the container.
|
||||
*
|
||||
* The deque stores pointers to items.
|
||||
* nsDequeBase implements the untyped deque data structure while
|
||||
* nsDeque provides the typed implementation and iterators.
|
||||
*/
|
||||
class nsDeque {
|
||||
typedef mozilla::fallible_t fallible_t;
|
||||
|
||||
class nsDequeBase {
|
||||
public:
|
||||
/**
|
||||
* Constructs an empty deque.
|
||||
*
|
||||
* @param aDeallocator Optional deallocator functor that will be called from
|
||||
* Erase() and the destructor on any remaining item.
|
||||
* The deallocator is owned by the deque and will be
|
||||
* deleted at destruction time.
|
||||
*/
|
||||
explicit nsDeque(nsDequeFunctor* aDeallocator = nullptr);
|
||||
|
||||
/**
|
||||
* Deque destructor. Erases all items, deletes the deallocator.
|
||||
*/
|
||||
~nsDeque();
|
||||
|
||||
/**
|
||||
* Returns the number of items currently stored in
|
||||
* this deque.
|
||||
|
@ -82,16 +54,23 @@ class nsDeque {
|
|||
*/
|
||||
inline size_t GetSize() const { return mSize; }
|
||||
|
||||
protected:
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
/**
|
||||
* Appends new member at the end of the deque.
|
||||
* Constructs an empty deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
* @param aDeallocator Optional deallocator functor that will be called from
|
||||
* Erase() and the destructor on any remaining item.
|
||||
* The deallocator is owned by the deque and will be
|
||||
* deleted at destruction time.
|
||||
*/
|
||||
void Push(void* aItem) {
|
||||
if (!Push(aItem, mozilla::fallible)) {
|
||||
NS_ABORT_OOM(mSize * sizeof(void*));
|
||||
}
|
||||
}
|
||||
explicit nsDequeBase();
|
||||
|
||||
/**
|
||||
* Deque destructor. Erases all items, deletes the deallocator.
|
||||
*/
|
||||
~nsDequeBase();
|
||||
|
||||
/**
|
||||
* Appends new member at the end of the deque.
|
||||
|
@ -101,17 +80,6 @@ class nsDeque {
|
|||
*/
|
||||
[[nodiscard]] bool Push(void* aItem, const fallible_t&);
|
||||
|
||||
/**
|
||||
* Inserts new member at the front of the deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
*/
|
||||
void PushFront(void* aItem) {
|
||||
if (!PushFront(aItem, mozilla::fallible)) {
|
||||
NS_ABORT_OOM(mSize * sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new member at the front of the deque.
|
||||
*
|
||||
|
@ -156,12 +124,171 @@ class nsDeque {
|
|||
*/
|
||||
void* ObjectAt(size_t aIndex) const;
|
||||
|
||||
bool GrowCapacity();
|
||||
|
||||
/**
|
||||
* Remove all items from container without destroying them.
|
||||
*/
|
||||
void Empty();
|
||||
|
||||
size_t mSize;
|
||||
size_t mCapacity;
|
||||
size_t mOrigin;
|
||||
void* mBuffer[8];
|
||||
void** mData;
|
||||
|
||||
nsDequeBase& operator=(const nsDequeBase& aOther) = delete;
|
||||
nsDequeBase(const nsDequeBase& aOther) = delete;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* The nsDequeFunctor class is used when you want to create
|
||||
* callbacks between the deque and your generic code.
|
||||
* Use these objects in a call to ForEach(), and as custom deallocators.
|
||||
*/
|
||||
template <typename T>
|
||||
class nsDequeFunctor {
|
||||
public:
|
||||
virtual void operator()(T* aObject) = 0;
|
||||
virtual ~nsDequeFunctor() = default;
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Here comes the nsDeque class itself...
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* The deque (double-ended queue) class is a common container type,
|
||||
* 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.
|
||||
*
|
||||
* The deque stores pointers to items.
|
||||
*/
|
||||
template <typename T>
|
||||
class nsDeque : public mozilla::detail::nsDequeBase {
|
||||
typedef mozilla::fallible_t fallible_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs an empty deque.
|
||||
*
|
||||
* @param aDeallocator Optional deallocator functor that will be called from
|
||||
* Erase() and the destructor on any remaining item.
|
||||
* The deallocator is owned by the deque and will be
|
||||
* deleted at destruction time.
|
||||
*/
|
||||
explicit nsDeque(nsDequeFunctor<T>* aDeallocator = nullptr) {
|
||||
MOZ_COUNT_CTOR(nsDeque);
|
||||
mDeallocator = aDeallocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deque destructor. Erases all items, deletes the deallocator.
|
||||
*/
|
||||
~nsDeque() {
|
||||
MOZ_COUNT_DTOR(nsDeque);
|
||||
|
||||
Erase();
|
||||
SetDeallocator(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends new member at the end of the deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
*/
|
||||
inline void Push(T* aItem) {
|
||||
if (!nsDequeBase::Push(aItem, mozilla::fallible)) {
|
||||
NS_ABORT_OOM(mSize * sizeof(T*));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends new member at the end of the deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
* @return true if succeeded, false if failed to resize deque as needed
|
||||
*/
|
||||
[[nodiscard]] inline bool Push(T* aItem, const fallible_t& aFaillible) {
|
||||
return nsDequeBase::Push(aItem, aFaillible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new member at the front of the deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
*/
|
||||
inline void PushFront(T* aItem) {
|
||||
if (!nsDequeBase::PushFront(aItem, mozilla::fallible)) {
|
||||
NS_ABORT_OOM(mSize * sizeof(T*));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new member at the front of the deque.
|
||||
*
|
||||
* @param aItem item to store in deque
|
||||
* @return true if succeeded, false if failed to resize deque as needed
|
||||
*/
|
||||
[[nodiscard]] bool PushFront(T* aItem, const fallible_t& aFallible) {
|
||||
return nsDequeBase::PushFront(aItem, aFallible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and return the last item in the container.
|
||||
*
|
||||
* @return the item that was the last item in container
|
||||
*/
|
||||
inline T* Pop() { return static_cast<T*>(nsDequeBase::Pop()); }
|
||||
|
||||
/**
|
||||
* Remove and return the first item in the container.
|
||||
*
|
||||
* @return the item that was first item in container
|
||||
*/
|
||||
inline T* PopFront() { return static_cast<T*>(nsDequeBase::PopFront()); }
|
||||
|
||||
/**
|
||||
* Retrieve the last item without removing it.
|
||||
*
|
||||
* @return the last item in container
|
||||
*/
|
||||
inline T* Peek() const { return static_cast<T*>(nsDequeBase::Peek()); }
|
||||
|
||||
/**
|
||||
* Retrieve the first item without removing it.
|
||||
*
|
||||
* @return the first item in container
|
||||
*/
|
||||
inline T* PeekFront() const {
|
||||
return static_cast<T*>(nsDequeBase::PeekFront());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a member from the deque without removing it.
|
||||
*
|
||||
* @param index of desired item
|
||||
* @return item in list, or nullptr if index is outside the deque
|
||||
*/
|
||||
inline T* ObjectAt(size_t aIndex) const {
|
||||
return static_cast<T*>(nsDequeBase::ObjectAt(aIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and delete all items from container.
|
||||
* Deletes are handled by the deallocator nsDequeFunctor
|
||||
* which is specified at deque construction.
|
||||
*/
|
||||
void Erase();
|
||||
void Erase() {
|
||||
if (mDeallocator && mSize) {
|
||||
ForEach(*mDeallocator);
|
||||
}
|
||||
Empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you want to iterate through all
|
||||
|
@ -173,7 +300,11 @@ class nsDeque {
|
|||
*
|
||||
* @param aFunctor object to call for each member
|
||||
*/
|
||||
void ForEach(nsDequeFunctor& aFunctor) const;
|
||||
void ForEach(nsDequeFunctor<T>& aFunctor) const {
|
||||
for (size_t i = 0; i < mSize; ++i) {
|
||||
aFunctor(ObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
// This iterator assumes that the deque itself is const, i.e., it cannot be
|
||||
// modified while the iterator is used.
|
||||
|
@ -194,7 +325,7 @@ class nsDeque {
|
|||
bool operator!=(const ConstDequeIterator& aOther) const {
|
||||
return mIndex != aOther.mIndex;
|
||||
}
|
||||
void* operator*() const {
|
||||
T* operator*() const {
|
||||
// Don't allow out-of-deque dereferences.
|
||||
MOZ_RELEASE_ASSERT(mIndex < mDeque.GetSize());
|
||||
return mDeque.ObjectAt(mIndex);
|
||||
|
@ -233,7 +364,7 @@ class nsDeque {
|
|||
bool operator!=(const ConstIterator& aOther) const {
|
||||
return EffectiveIndex() != aOther.EffectiveIndex();
|
||||
}
|
||||
void* operator*() const {
|
||||
T* operator*() const {
|
||||
// Don't allow out-of-deque dereferences.
|
||||
MOZ_RELEASE_ASSERT(mIndex < mDeque.GetSize());
|
||||
return mDeque.ObjectAt(mIndex);
|
||||
|
@ -256,16 +387,20 @@ class nsDeque {
|
|||
return ConstIterator(*this, ConstIterator::EndIteratorIndex);
|
||||
}
|
||||
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t size = nsDequeBase::SizeOfExcludingThis(aMallocSizeOf);
|
||||
if (mDeallocator) {
|
||||
size += aMallocSizeOf(mDeallocator);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t mSize;
|
||||
size_t mCapacity;
|
||||
size_t mOrigin;
|
||||
nsDequeFunctor* mDeallocator;
|
||||
void* mBuffer[8];
|
||||
void** mData;
|
||||
nsDequeFunctor<T>* mDeallocator;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -283,12 +418,9 @@ class nsDeque {
|
|||
*/
|
||||
nsDeque& operator=(const nsDeque& aOther) = delete;
|
||||
|
||||
bool GrowCapacity();
|
||||
void SetDeallocator(nsDequeFunctor* aDeallocator);
|
||||
|
||||
/**
|
||||
* Remove all items from container without destroying them.
|
||||
*/
|
||||
void Empty();
|
||||
void SetDeallocator(nsDequeFunctor<T>* aDeallocator) {
|
||||
delete mDeallocator;
|
||||
mDeallocator = aDeallocator;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -17,31 +17,32 @@
|
|||
**************************************************************/
|
||||
namespace TestNsDeque {
|
||||
|
||||
class _Dealloc : public nsDequeFunctor {
|
||||
virtual void operator()(void* aObject) {}
|
||||
template <typename T>
|
||||
class _Dealloc : public nsDequeFunctor<T> {
|
||||
virtual void operator()(T* aObject) {}
|
||||
};
|
||||
|
||||
static bool VerifyContents(const nsDeque& aDeque, const int* aContents,
|
||||
static bool VerifyContents(const nsDeque<int>& aDeque, const int* aContents,
|
||||
size_t aLength) {
|
||||
for (size_t i = 0; i < aLength; ++i) {
|
||||
if (*(int*)aDeque.ObjectAt(i) != aContents[i]) {
|
||||
if (*aDeque.ObjectAt(i) != aContents[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class Deallocator : public nsDequeFunctor {
|
||||
virtual void operator()(void* aObject) {
|
||||
class Deallocator : public nsDequeFunctor<int> {
|
||||
virtual void operator()(int* aObject) {
|
||||
if (aObject) {
|
||||
// Set value to -1, to use in test function.
|
||||
*((int*)aObject) = -1;
|
||||
*(aObject) = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ForEachAdder : public nsDequeFunctor {
|
||||
virtual void operator()(void* aObject) {
|
||||
class ForEachAdder : public nsDequeFunctor<int> {
|
||||
virtual void operator()(int* aObject) {
|
||||
if (aObject) {
|
||||
sum += *(int*)aObject;
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ TEST(NsDeque, OriginalTest)
|
|||
int ints[size];
|
||||
size_t i = 0;
|
||||
int temp;
|
||||
nsDeque theDeque(new _Dealloc); // construct a simple one...
|
||||
nsDeque<int> theDeque(new _Dealloc<int>); // construct a simple one...
|
||||
|
||||
// ints = [0...199]
|
||||
for (i = 0; i < size; i++) { // initialize'em
|
||||
|
@ -72,7 +73,7 @@ TEST(NsDeque, OriginalTest)
|
|||
// queue = [0...69]
|
||||
for (i = 0; i < 70; i++) {
|
||||
theDeque.Push(&ints[i]);
|
||||
temp = *(int*)theDeque.Peek();
|
||||
temp = *theDeque.Peek();
|
||||
EXPECT_EQ(static_cast<int>(i), temp) << "Verify end after push #1";
|
||||
EXPECT_EQ(i + 1, theDeque.GetSize()) << "Verify size after push #1";
|
||||
}
|
||||
|
@ -81,7 +82,7 @@ TEST(NsDeque, OriginalTest)
|
|||
|
||||
// queue = [0...14]
|
||||
for (i = 1; i <= 55; i++) {
|
||||
temp = *(int*)theDeque.Pop();
|
||||
temp = *theDeque.Pop();
|
||||
EXPECT_EQ(70 - static_cast<int>(i), temp) << "Verify end after pop # 1";
|
||||
EXPECT_EQ(70u - i, theDeque.GetSize()) << "Verify size after pop # 1";
|
||||
}
|
||||
|
@ -90,7 +91,7 @@ TEST(NsDeque, OriginalTest)
|
|||
// queue = [0...14,0...54]
|
||||
for (i = 0; i < 55; i++) {
|
||||
theDeque.Push(&ints[i]);
|
||||
temp = *(int*)theDeque.Peek();
|
||||
temp = *theDeque.Peek();
|
||||
EXPECT_EQ(static_cast<int>(i), temp) << "Verify end after push #2";
|
||||
EXPECT_EQ(i + 15u + 1, theDeque.GetSize()) << "Verify size after push # 2";
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ TEST(NsDeque, OriginalTest)
|
|||
|
||||
// queue = [0...14,0...19]
|
||||
for (i = 1; i <= 35; i++) {
|
||||
temp = *(int*)theDeque.Pop();
|
||||
temp = *theDeque.Pop();
|
||||
EXPECT_EQ(55 - static_cast<int>(i), temp) << "Verify end after pop # 2";
|
||||
EXPECT_EQ(70u - i, theDeque.GetSize()) << "Verify size after pop #2";
|
||||
}
|
||||
|
@ -109,26 +110,26 @@ TEST(NsDeque, OriginalTest)
|
|||
// queue = [0...14,0...19,0...34]
|
||||
for (i = 0; i < 35; i++) {
|
||||
theDeque.Push(&ints[i]);
|
||||
temp = *(int*)theDeque.Peek();
|
||||
temp = *theDeque.Peek();
|
||||
EXPECT_EQ(static_cast<int>(i), temp) << "Verify end after push # 3";
|
||||
EXPECT_EQ(35u + 1u + i, theDeque.GetSize()) << "Verify size after push #3";
|
||||
}
|
||||
|
||||
// queue = [0...14,0...19]
|
||||
for (i = 0; i < 35; i++) {
|
||||
temp = *(int*)theDeque.Pop();
|
||||
temp = *theDeque.Pop();
|
||||
EXPECT_EQ(34 - static_cast<int>(i), temp) << "Verify end after pop # 3";
|
||||
}
|
||||
|
||||
// queue = [0...14]
|
||||
for (i = 0; i < 20; i++) {
|
||||
temp = *(int*)theDeque.Pop();
|
||||
temp = *theDeque.Pop();
|
||||
EXPECT_EQ(19 - static_cast<int>(i), temp) << "Verify end after pop # 4";
|
||||
}
|
||||
|
||||
// queue = []
|
||||
for (i = 0; i < 15; i++) {
|
||||
temp = *(int*)theDeque.Pop();
|
||||
temp = *theDeque.Pop();
|
||||
EXPECT_EQ(14 - static_cast<int>(i), temp) << "Verify end after pop # 5";
|
||||
}
|
||||
|
||||
|
@ -140,7 +141,7 @@ TEST(NsDeque, OriginalFlaw)
|
|||
int ints[200];
|
||||
int i = 0;
|
||||
int temp;
|
||||
nsDeque d(new _Dealloc);
|
||||
nsDeque<int> d(new _Dealloc<int>);
|
||||
/**
|
||||
* Test 1. Origin near end, semi full, call Peek().
|
||||
* you start, mCapacity is 8
|
||||
|
@ -149,13 +150,13 @@ TEST(NsDeque, OriginalFlaw)
|
|||
|
||||
for (i = 0; i < 6; i++) {
|
||||
d.Push(&ints[i]);
|
||||
temp = *(int*)d.Peek();
|
||||
temp = *d.Peek();
|
||||
EXPECT_EQ(i, temp) << "OriginalFlaw push #1";
|
||||
}
|
||||
EXPECT_EQ(6u, d.GetSize()) << "OriginalFlaw size check #1";
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
temp = *(int*)d.PopFront();
|
||||
temp = *d.PopFront();
|
||||
EXPECT_EQ(i, temp) << "PopFront test";
|
||||
}
|
||||
// d = [4,5]
|
||||
|
@ -167,14 +168,14 @@ TEST(NsDeque, OriginalFlaw)
|
|||
|
||||
// d = [4...9]
|
||||
for (i = 4; i <= 9; i++) {
|
||||
temp = *(int*)d.PopFront();
|
||||
temp = *d.PopFront();
|
||||
EXPECT_EQ(i, temp) << "OriginalFlaw empty check";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NsDeque, TestObjectAt)
|
||||
{
|
||||
nsDeque d;
|
||||
nsDeque<int> d;
|
||||
const int count = 10;
|
||||
int ints[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
@ -190,7 +191,7 @@ TEST(NsDeque, TestObjectAt)
|
|||
|
||||
// d = [2..5]
|
||||
for (size_t i = 2; i <= 5; i++) {
|
||||
int t = *(int*)d.ObjectAt(i - 2);
|
||||
int t = *d.ObjectAt(i - 2);
|
||||
EXPECT_EQ(static_cast<int>(i), t) << "Verify ObjectAt()";
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +203,7 @@ TEST(NsDeque, TestPushFront)
|
|||
// - wrapping around works properly
|
||||
// - growing works properly
|
||||
|
||||
nsDeque d;
|
||||
nsDeque<int> d;
|
||||
|
||||
const int kPoolSize = 10;
|
||||
const size_t kMaxSizeBeforeGrowth = 8;
|
||||
|
@ -239,7 +240,8 @@ TEST(NsDeque, TestPushFront)
|
|||
<< "verify pushfront 3";
|
||||
}
|
||||
|
||||
static void CheckIfQueueEmpty(nsDeque& d) {
|
||||
template <typename T>
|
||||
static void CheckIfQueueEmpty(nsDeque<T>& d) {
|
||||
EXPECT_EQ(0u, d.GetSize()) << "Size should be 0";
|
||||
EXPECT_EQ(nullptr, d.Pop()) << "Invalid operation should return nullptr";
|
||||
EXPECT_EQ(nullptr, d.PopFront()) << "Invalid operation should return nullptr";
|
||||
|
@ -253,7 +255,7 @@ static void CheckIfQueueEmpty(nsDeque& d) {
|
|||
TEST(NsDeque, TestEmpty)
|
||||
{
|
||||
// Make sure nsDeque gives sane results if it's empty.
|
||||
nsDeque d;
|
||||
nsDeque<void> d;
|
||||
size_t numberOfEntries = 8;
|
||||
|
||||
CheckIfQueueEmpty(d);
|
||||
|
@ -275,7 +277,7 @@ TEST(NsDeque, TestEmpty)
|
|||
|
||||
TEST(NsDeque, TestEraseMethod)
|
||||
{
|
||||
nsDeque d;
|
||||
nsDeque<void> d;
|
||||
const size_t numberOfEntries = 8;
|
||||
|
||||
// Fill it up before calling Erase
|
||||
|
@ -292,14 +294,14 @@ TEST(NsDeque, TestEraseMethod)
|
|||
|
||||
TEST(NsDeque, TestEraseShouldCallDeallocator)
|
||||
{
|
||||
nsDeque d(new Deallocator());
|
||||
nsDeque<int> d(new Deallocator());
|
||||
const size_t NumTestValues = 8;
|
||||
|
||||
int* testArray[NumTestValues];
|
||||
for (size_t i = 0; i < NumTestValues; i++) {
|
||||
testArray[i] = new int();
|
||||
*(testArray[i]) = i;
|
||||
d.Push((void*)testArray[i]);
|
||||
d.Push(testArray[i]);
|
||||
}
|
||||
|
||||
d.Erase();
|
||||
|
@ -315,7 +317,7 @@ TEST(NsDeque, TestEraseShouldCallDeallocator)
|
|||
|
||||
TEST(NsDeque, TestForEach)
|
||||
{
|
||||
nsDeque d(new Deallocator());
|
||||
nsDeque<int> d(new Deallocator());
|
||||
const size_t NumTestValues = 8;
|
||||
int sum = 0;
|
||||
|
||||
|
@ -324,7 +326,7 @@ TEST(NsDeque, TestForEach)
|
|||
testArray[i] = new int();
|
||||
*(testArray[i]) = i;
|
||||
sum += i;
|
||||
d.Push((void*)testArray[i]);
|
||||
d.Push(testArray[i]);
|
||||
}
|
||||
|
||||
ForEachAdder adder;
|
||||
|
@ -336,7 +338,7 @@ TEST(NsDeque, TestForEach)
|
|||
|
||||
TEST(NsDeque, TestConstRangeFor)
|
||||
{
|
||||
nsDeque d(new Deallocator());
|
||||
nsDeque<int> d(new Deallocator());
|
||||
|
||||
const size_t NumTestValues = 3;
|
||||
for (size_t i = 0; i < NumTestValues; ++i) {
|
||||
|
@ -344,16 +346,17 @@ TEST(NsDeque, TestConstRangeFor)
|
|||
}
|
||||
|
||||
static_assert(
|
||||
std::is_same_v<nsDeque::ConstDequeIterator,
|
||||
decltype(std::declval<const nsDeque&>().begin())>,
|
||||
std::is_same_v<nsDeque<int>::ConstDequeIterator,
|
||||
decltype(std::declval<const nsDeque<int>&>().begin())>,
|
||||
"(const nsDeque).begin() should return ConstDequeIterator");
|
||||
static_assert(std::is_same_v<nsDeque::ConstDequeIterator,
|
||||
decltype(std::declval<const nsDeque&>().end())>,
|
||||
"(const nsDeque).end() should return ConstDequeIterator");
|
||||
static_assert(
|
||||
std::is_same_v<nsDeque<int>::ConstDequeIterator,
|
||||
decltype(std::declval<const nsDeque<int>&>().end())>,
|
||||
"(const nsDeque).end() should return ConstDequeIterator");
|
||||
|
||||
int sum = 0;
|
||||
for (void* ob : const_cast<const nsDeque&>(d)) {
|
||||
sum += *static_cast<int*>(ob);
|
||||
for (int* ob : const_cast<const nsDeque<int>&>(d)) {
|
||||
sum += *ob;
|
||||
}
|
||||
EXPECT_EQ(1 + 2 + 3, sum) << "Const-range-for should iterate over values";
|
||||
}
|
||||
|
@ -363,73 +366,76 @@ TEST(NsDeque, TestRangeFor)
|
|||
const size_t NumTestValues = 3;
|
||||
struct Test {
|
||||
size_t runAfterLoopCount;
|
||||
std::function<void(nsDeque&)> function;
|
||||
std::function<void(nsDeque<int>&)> function;
|
||||
int expectedSum;
|
||||
const char* description;
|
||||
};
|
||||
// Note: All tests start with a deque containing 3 pointers to ints 1, 2, 3.
|
||||
Test tests[] = {
|
||||
{0, [](nsDeque& d) {}, 1 + 2 + 3, "no changes"},
|
||||
{0, [](nsDeque<int>& d) {}, 1 + 2 + 3, "no changes"},
|
||||
|
||||
{1, [](nsDeque& d) { d.Pop(); }, 1 + 2, "Pop after 1st loop"},
|
||||
{2, [](nsDeque& d) { d.Pop(); }, 1 + 2, "Pop after 2nd loop"},
|
||||
{3, [](nsDeque& d) { d.Pop(); }, 1 + 2 + 3, "Pop after 3rd loop"},
|
||||
{1, [](nsDeque<int>& d) { d.Pop(); }, 1 + 2, "Pop after 1st loop"},
|
||||
{2, [](nsDeque<int>& d) { d.Pop(); }, 1 + 2, "Pop after 2nd loop"},
|
||||
{3, [](nsDeque<int>& d) { d.Pop(); }, 1 + 2 + 3, "Pop after 3rd loop"},
|
||||
|
||||
{1, [](nsDeque& d) { d.PopFront(); }, 1 + 3, "PopFront after 1st loop"},
|
||||
{2, [](nsDeque& d) { d.PopFront(); }, 1 + 2, "PopFront after 2nd loop"},
|
||||
{3, [](nsDeque& d) { d.PopFront(); }, 1 + 2 + 3,
|
||||
{1, [](nsDeque<int>& d) { d.PopFront(); }, 1 + 3,
|
||||
"PopFront after 1st loop"},
|
||||
{2, [](nsDeque<int>& d) { d.PopFront(); }, 1 + 2,
|
||||
"PopFront after 2nd loop"},
|
||||
{3, [](nsDeque<int>& d) { d.PopFront(); }, 1 + 2 + 3,
|
||||
"PopFront after 3rd loop"},
|
||||
|
||||
{1, [](nsDeque& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
{1, [](nsDeque<int>& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
"Push after 1st loop"},
|
||||
{2, [](nsDeque& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
{2, [](nsDeque<int>& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
"Push after 2nd loop"},
|
||||
{3, [](nsDeque& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
{3, [](nsDeque<int>& d) { d.Push(new int(4)); }, 1 + 2 + 3 + 4,
|
||||
"Push after 3rd loop"},
|
||||
{4, [](nsDeque& d) { d.Push(new int(4)); }, 1 + 2 + 3,
|
||||
{4, [](nsDeque<int>& d) { d.Push(new int(4)); }, 1 + 2 + 3,
|
||||
"Push after would-be-4th loop"},
|
||||
|
||||
{1, [](nsDeque& d) { d.PushFront(new int(4)); }, 1 + 1 + 2 + 3,
|
||||
{1, [](nsDeque<int>& d) { d.PushFront(new int(4)); }, 1 + 1 + 2 + 3,
|
||||
"PushFront after 1st loop"},
|
||||
{2, [](nsDeque& d) { d.PushFront(new int(4)); }, 1 + 2 + 2 + 3,
|
||||
{2, [](nsDeque<int>& d) { d.PushFront(new int(4)); }, 1 + 2 + 2 + 3,
|
||||
"PushFront after 2nd loop"},
|
||||
{3, [](nsDeque& d) { d.PushFront(new int(4)); }, 1 + 2 + 3 + 3,
|
||||
{3, [](nsDeque<int>& d) { d.PushFront(new int(4)); }, 1 + 2 + 3 + 3,
|
||||
"PushFront after 3rd loop"},
|
||||
{4, [](nsDeque& d) { d.PushFront(new int(4)); }, 1 + 2 + 3,
|
||||
{4, [](nsDeque<int>& d) { d.PushFront(new int(4)); }, 1 + 2 + 3,
|
||||
"PushFront after would-be-4th loop"},
|
||||
|
||||
{1, [](nsDeque& d) { d.Erase(); }, 1, "Erase after 1st loop"},
|
||||
{2, [](nsDeque& d) { d.Erase(); }, 1 + 2, "Erase after 2nd loop"},
|
||||
{3, [](nsDeque& d) { d.Erase(); }, 1 + 2 + 3, "Erase after 3rd loop"},
|
||||
{1, [](nsDeque<int>& d) { d.Erase(); }, 1, "Erase after 1st loop"},
|
||||
{2, [](nsDeque<int>& d) { d.Erase(); }, 1 + 2, "Erase after 2nd loop"},
|
||||
{3, [](nsDeque<int>& d) { d.Erase(); }, 1 + 2 + 3,
|
||||
"Erase after 3rd loop"},
|
||||
|
||||
{1,
|
||||
[](nsDeque& d) {
|
||||
[](nsDeque<int>& d) {
|
||||
d.Erase();
|
||||
d.Push(new int(4));
|
||||
},
|
||||
1, "Erase after 1st loop, Push 4"},
|
||||
{1,
|
||||
[](nsDeque& d) {
|
||||
[](nsDeque<int>& d) {
|
||||
d.Erase();
|
||||
d.Push(new int(4));
|
||||
d.Push(new int(5));
|
||||
},
|
||||
1 + 5, "Erase after 1st loop, Push 4,5"},
|
||||
{2,
|
||||
[](nsDeque& d) {
|
||||
[](nsDeque<int>& d) {
|
||||
d.Erase();
|
||||
d.Push(new int(4));
|
||||
},
|
||||
1 + 2, "Erase after 2nd loop, Push 4"},
|
||||
{2,
|
||||
[](nsDeque& d) {
|
||||
[](nsDeque<int>& d) {
|
||||
d.Erase();
|
||||
d.Push(new int(4));
|
||||
d.Push(new int(5));
|
||||
},
|
||||
1 + 2, "Erase after 2nd loop, Push 4,5"},
|
||||
{2,
|
||||
[](nsDeque& d) {
|
||||
[](nsDeque<int>& d) {
|
||||
d.Erase();
|
||||
d.Push(new int(4));
|
||||
d.Push(new int(5));
|
||||
|
@ -438,21 +444,23 @@ TEST(NsDeque, TestRangeFor)
|
|||
1 + 2 + 6, "Erase after 2nd loop, Push 4,5,6"}};
|
||||
|
||||
for (const Test& test : tests) {
|
||||
nsDeque d(new Deallocator());
|
||||
nsDeque<int> d(new Deallocator());
|
||||
|
||||
for (size_t i = 0; i < NumTestValues; ++i) {
|
||||
d.Push(new int(i + 1));
|
||||
}
|
||||
|
||||
static_assert(std::is_same_v<nsDeque::ConstIterator, decltype(d.begin())>,
|
||||
"(non-const nsDeque).begin() should return ConstIterator");
|
||||
static_assert(std::is_same_v<nsDeque::ConstIterator, decltype(d.end())>,
|
||||
"(non-const nsDeque).end() should return ConstIterator");
|
||||
static_assert(
|
||||
std::is_same_v<nsDeque<int>::ConstIterator, decltype(d.begin())>,
|
||||
"(non-const nsDeque).begin() should return ConstIterator");
|
||||
static_assert(
|
||||
std::is_same_v<nsDeque<int>::ConstIterator, decltype(d.end())>,
|
||||
"(non-const nsDeque).end() should return ConstIterator");
|
||||
|
||||
int sum = 0;
|
||||
size_t loopCount = 0;
|
||||
for (void* ob : d) {
|
||||
sum += *static_cast<int*>(ob);
|
||||
for (int* ob : d) {
|
||||
sum += *ob;
|
||||
if (++loopCount == test.runAfterLoopCount) {
|
||||
test.function(d);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче