Bug 493701 - part 1: add nsTObserverArray::BackwardIterator; r=bzbarsky

--HG--
extra : rebase_source : cb875dcd70b76b819abb1d516db74e55a3babd54
This commit is contained in:
Arpad Borsos 2013-12-10 13:28:31 +01:00
parent a13e822000
commit 483e7be532
2 changed files with 87 additions and 4 deletions

View File

@ -242,6 +242,11 @@ class nsAutoTObserverArray : protected nsTObserverArray_base {
ClearIterators();
}
// Compact the array to minimize the memory it uses
void Compact() {
mArray.Compact();
}
// Returns the number of bytes on the heap taken up by this object, not
// including sizeof(*this).
size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
@ -349,6 +354,45 @@ class nsAutoTObserverArray : protected nsTObserverArray_base {
ForwardIterator mEnd;
};
// Iterates the array backward from end to start. mPosition points
// to the element that was returned last.
// Elements:
// - prepended to the array during iteration *will* be traversed,
// unless the iteration already arrived at the first element
// - appended during iteration *will not* be traversed
// - removed during iteration *will not* be traversed.
class BackwardIterator : protected Iterator {
public:
typedef nsAutoTObserverArray<T, N> array_type;
typedef Iterator base_type;
BackwardIterator(const array_type& aArray)
: Iterator(aArray.Length(), aArray) {
}
// Returns true if there are more elements to iterate.
// This must precede a call to GetNext(). If false is
// returned, GetNext() must not be called.
bool HasMore() const {
return base_type::mPosition > 0;
}
// Returns the next element and steps one step. This must
// be preceded by a call to HasMore().
// @return The next observer.
elem_type& GetNext() {
NS_ASSERTION(HasMore(), "iterating beyond start of array");
return base_type::mArray.ElementAt(--base_type::mPosition);
}
// Removes the element at the current iterator position.
// (the last element returned from |GetNext()|)
// This will not affect the next call to |GetNext()|
void Remove() {
return base_type::mArray.RemoveElementAt(base_type::mPosition);
}
};
protected:
nsAutoTArray<T, N> mArray;
};

View File

@ -131,8 +131,7 @@ int main(int argc, char **argv)
arr.PrependElementUnlessExists(7);
DO_TEST(ForwardIterator, test19Expected, { /* nothing */ });
// Commented out because it fails; bug 474369 will fix
/* DO_TEST(ForwardIterator, test19Expected,
DO_TEST(ForwardIterator, test19Expected,
if (count == 1) {
arr.PrependElementUnlessExists(9);
}
@ -140,7 +139,47 @@ int main(int argc, char **argv)
static int test22Expected[] = { 9, 3, 4, 7, 2, 8 };
DO_TEST(ForwardIterator, test22Expected, { });
*/
// BackwardIterator
static int test23Expected[] = { 8, 2, 7, 4, 3, 9 };
DO_TEST(BackwardIterator, test23Expected, );
// Removals
static int test24Expected[] = { 8, 2, 7, 4, 9 };
DO_TEST(BackwardIterator, test24Expected,
if (count == 1) arr.RemoveElementAt(1);
);
// Appends
DO_TEST(BackwardIterator, test24Expected,
if (count == 1) arr.AppendElement(1);
);
static int test26Expected[] = { 1, 8, 2, 7, 4, 9 };
DO_TEST(BackwardIterator, test26Expected, );
// Prepends
static int test27Expected[] = { 1, 8, 2, 7, 4, 9, 3 };
DO_TEST(BackwardIterator, test27Expected,
if (count == 1) arr.PrependElementUnlessExists(3);
);
// Removal using Iterator
DO_TEST(BackwardIterator, test27Expected,
// when this code runs, |GetNext()| has only been called once, so
// this actually removes the very first element
if (count == 1) iter.Remove();
);
static int test28Expected[] = { 8, 2, 7, 4, 9, 3 };
DO_TEST(BackwardIterator, test28Expected, );
/**
* Note: _code is executed before the call to GetNext(), it can therefore not
* test the case of prepending when the BackwardIterator already returned the
* first element.
* In that case BackwardIterator does not traverse the newly prepended Element
*/
return rv;
}