Bug 1143513 - Make nsFrameList compatible with range-based syntax and utils. r=roc,waldo

This commit is contained in:
Xidorn Quan 2015-03-31 14:08:17 +11:00
parent 36760511f3
commit 6ccb78f80a
2 changed files with 90 additions and 0 deletions

View File

@ -9,6 +9,7 @@
#include <stdio.h> /* for FILE* */
#include "nsDebug.h"
#include "nsTArrayForwardDeclare.h"
#include "mozilla/ReverseIterator.h"
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
// DEBUG_FRAME_DUMP enables nsIFrame::List and related methods.
@ -447,6 +448,56 @@ public:
nsIFrame* mPrev;
};
class Iterator
{
public:
typedef nsIFrame* const ValueType;
// Though we don't support +/- a integer currently,
// iterators have to have a DifferenceType.
typedef ptrdiff_t DifferenceType;
Iterator(const nsFrameList& aList, nsIFrame* aCurrent)
: mList(aList)
, mCurrent(aCurrent)
{}
Iterator(const Iterator& aOther)
: mList(aOther.mList)
, mCurrent(aOther.mCurrent)
{}
ValueType& operator*() const { return mCurrent; }
// The operators need to know about nsIFrame, hence the
// implementations are in nsIFrame.h
Iterator& operator++();
Iterator& operator--();
Iterator operator++(int) { auto ret = *this; ++*this; return ret; }
Iterator operator--(int) { auto ret = *this; --*this; return ret; }
friend bool operator==(const Iterator& aIter1, const Iterator& aIter2);
friend bool operator!=(const Iterator& aIter1, const Iterator& aIter2);
private:
const nsFrameList& mList;
nsIFrame* mCurrent;
};
typedef Iterator iterator;
typedef Iterator const_iterator;
typedef mozilla::ReverseIterator<Iterator> reverse_iterator;
typedef mozilla::ReverseIterator<Iterator> const_reverse_iterator;
iterator begin() const { return iterator(*this, mFirstChild); }
const_iterator cbegin() const { return begin(); }
iterator end() const { return iterator(*this, nullptr); }
const_iterator cend() const { return end(); }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
const_reverse_iterator crbegin() const { return rbegin(); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
const_reverse_iterator crend() const { return rend(); }
private:
void operator delete(void*) = delete;
@ -469,6 +520,24 @@ protected:
nsIFrame* mLastChild;
};
inline bool
operator==(const nsFrameList::Iterator& aIter1,
const nsFrameList::Iterator& aIter2)
{
MOZ_ASSERT(&aIter1.mList == &aIter2.mList,
"must not compare iterator from different list");
return aIter1.mCurrent == aIter2.mCurrent;
}
inline bool
operator!=(const nsFrameList::Iterator& aIter1,
const nsFrameList::Iterator& aIter2)
{
MOZ_ASSERT(&aIter1.mList == &aIter2.mList,
"Must not compare iterator from different list");
return aIter1.mCurrent != aIter2.mCurrent;
}
namespace mozilla {
namespace layout {

View File

@ -3348,6 +3348,27 @@ nsFrameList::FrameLinkEnumerator::Next()
Enumerator::Next();
}
// Operators of nsFrameList::Iterator
// ---------------------------------------------------
inline nsFrameList::Iterator&
nsFrameList::Iterator::operator++()
{
mCurrent = mCurrent->GetNextSibling();
return *this;
}
inline nsFrameList::Iterator&
nsFrameList::Iterator::operator--()
{
if (!mCurrent) {
mCurrent = mList.LastChild();
} else {
mCurrent = mCurrent->GetPrevSibling();
}
return *this;
}
// Helper-functions for nsIFrame::SortFrameList()
// ---------------------------------------------------