Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/nsFrameList.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef nsFrameList_h___
8
#define nsFrameList_h___
9
10
#include <stdio.h> /* for FILE* */
11
#include "nsDebug.h"
12
#include "nsTArray.h"
13
#include "mozilla/FunctionTypeTraits.h"
14
#include "mozilla/RefPtr.h"
15
#include "mozilla/ReverseIterator.h"
16
17
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
18
// DEBUG_FRAME_DUMP enables nsIFrame::List and related methods.
19
// You can also define this in a non-DEBUG build if you need frame dumps.
20
#define DEBUG_FRAME_DUMP 1
21
#endif
22
23
class nsContainerFrame;
24
class nsIContent;
25
class nsIFrame;
26
class nsIPresShell;
27
class nsPresContext;
28
29
namespace mozilla {
30
namespace layout {
31
  class FrameChildList;
32
  enum FrameChildListID {
33
      // The individual concrete child lists.
34
      kPrincipalList                = 0x1,
35
      kPopupList                    = 0x2,
36
      kCaptionList                  = 0x4,
37
      kColGroupList                 = 0x8,
38
      kSelectPopupList              = 0x10,
39
      kAbsoluteList                 = 0x20,
40
      kFixedList                    = 0x40,
41
      kOverflowList                 = 0x80,
42
      kOverflowContainersList       = 0x100,
43
      kExcessOverflowContainersList = 0x200,
44
      kOverflowOutOfFlowList        = 0x400,
45
      kFloatList                    = 0x800,
46
      kBulletList                   = 0x1000,
47
      kPushedFloatsList             = 0x2000,
48
      kBackdropList                 = 0x4000,
49
      // A special alias for kPrincipalList that suppress the reflow request that
50
      // is normally done when manipulating child lists.
51
      kNoReflowPrincipalList        = 0x8000
52
  };
53
54
  // A helper class for nsIFrame::Destroy[From].  It's defined here because
55
  // nsFrameList needs it and we can't use nsIFrame here.
56
  struct PostFrameDestroyData {
57
    PostFrameDestroyData(const PostFrameDestroyData&) = delete;
58
0
    PostFrameDestroyData() = default;
59
60
    AutoTArray<RefPtr<nsIContent>, 100> mAnonymousContent;
61
    void AddAnonymousContent(already_AddRefed<nsIContent>&& aContent)
62
0
    {
63
0
      mAnonymousContent.AppendElement(aContent);
64
0
    }
65
  };
66
} // namespace layout
67
} // namespace mozilla
68
69
// Uncomment this to enable expensive frame-list integrity checking
70
// #define DEBUG_FRAME_LIST
71
72
/**
73
 * A class for managing a list of frames.
74
 */
75
class nsFrameList {
76
public:
77
  nsFrameList() :
78
    mFirstChild(nullptr), mLastChild(nullptr)
79
0
  {
80
0
  }
81
82
  nsFrameList(nsIFrame* aFirstFrame, nsIFrame* aLastFrame) :
83
    mFirstChild(aFirstFrame), mLastChild(aLastFrame)
84
0
  {
85
0
    VerifyList();
86
0
  }
87
88
  nsFrameList(const nsFrameList& aOther) :
89
    mFirstChild(aOther.mFirstChild), mLastChild(aOther.mLastChild)
90
0
  {
91
0
  }
92
93
  /**
94
   * Infallibly allocate a nsFrameList from the shell arena.
95
   */
96
  void* operator new(size_t sz, nsIPresShell* aPresShell);
97
98
  /**
99
   * Deallocate this list that was allocated from the shell arena.
100
   * The list is required to be empty.
101
   */
102
  void Delete(nsIPresShell* aPresShell);
103
104
  /**
105
   * For each frame in this list: remove it from the list then call
106
   * Destroy() on it.
107
   */
108
  void DestroyFrames();
109
110
  /**
111
   * For each frame in this list: remove it from the list then call
112
   * DestroyFrom(aDestructRoot, aPostDestroyData) on it.
113
   */
114
  void DestroyFramesFrom(nsIFrame* aDestructRoot,
115
                         mozilla::layout::PostFrameDestroyData& aPostDestroyData);
116
117
0
  void Clear() { mFirstChild = mLastChild = nullptr; }
118
119
  void SetFrames(nsIFrame* aFrameList);
120
121
0
  void SetFrames(nsFrameList& aFrameList) {
122
0
    MOZ_ASSERT(!mFirstChild, "Losing frames");
123
0
124
0
    mFirstChild = aFrameList.FirstChild();
125
0
    mLastChild = aFrameList.LastChild();
126
0
    aFrameList.Clear();
127
0
  }
128
129
  class Slice;
130
131
  /**
132
   * Append aFrameList to this list.  If aParent is not null,
133
   * reparents the newly added frames.  Clears out aFrameList and
134
   * returns a list slice represening the newly-appended frames.
135
   */
136
0
  Slice AppendFrames(nsContainerFrame* aParent, nsFrameList& aFrameList) {
137
0
    return InsertFrames(aParent, LastChild(), aFrameList);
138
0
  }
139
140
141
  /**
142
   * Append aFrame to this list.  If aParent is not null,
143
   * reparents the newly added frame.
144
   */
145
0
  void AppendFrame(nsContainerFrame* aParent, nsIFrame* aFrame) {
146
0
    nsFrameList temp(aFrame, aFrame);
147
0
    AppendFrames(aParent, temp);
148
0
  }
149
150
  /**
151
   * Take aFrame out of the frame list. This also disconnects aFrame
152
   * from the sibling list. The frame must be non-null and present on
153
   * this list.
154
   */
155
  void RemoveFrame(nsIFrame* aFrame);
156
157
  /**
158
   * Take the frames after aAfterFrame out of the frame list.  If
159
   * aAfterFrame is null, removes the entire list.
160
   * @param aAfterFrame a frame in this list, or null
161
   * @return the removed frames, if any
162
   */
163
  nsFrameList RemoveFramesAfter(nsIFrame* aAfterFrame);
164
165
  /**
166
   * Take the first frame (if any) out of the frame list.
167
   * @return the first child, or nullptr if the list is empty
168
   */
169
  nsIFrame* RemoveFirstChild();
170
171
  /**
172
   * The following two functions are intended to be used in concert for
173
   * removing a frame from its frame list when the set of possible frame
174
   * lists is known in advance, but the exact frame list is unknown.
175
   * aFrame must be non-null.
176
   * Example use:
177
   *   bool removed = frameList1.StartRemoveFrame(aFrame) ||
178
   *                  frameList2.ContinueRemoveFrame(aFrame) ||
179
   *                  frameList3.ContinueRemoveFrame(aFrame);
180
   *   MOZ_ASSERT(removed);
181
   *
182
   * @note One of the frame lists MUST contain aFrame, if it's on some other
183
   *       frame list then the example above will likely lead to crashes.
184
   * This function is O(1).
185
   * @return true iff aFrame was removed from /some/ list, not necessarily
186
   *         this one.  If it was removed from a different list then it is
187
   *         guaranteed that that list is still non-empty.
188
   * (this method is implemented in nsIFrame.h to be able to inline)
189
   */
190
  inline bool StartRemoveFrame(nsIFrame* aFrame);
191
192
  /**
193
   * Precondition: StartRemoveFrame MUST be called before this.
194
   * This function is O(1).
195
   * @see StartRemoveFrame
196
   * @return true iff aFrame was removed from this list
197
   * (this method is implemented in nsIFrame.h to be able to inline)
198
   */
199
  inline bool ContinueRemoveFrame(nsIFrame* aFrame);
200
201
  /**
202
   * Take aFrame out of the frame list and then destroy it.
203
   * The frame must be non-null and present on this list.
204
   */
205
  void DestroyFrame(nsIFrame* aFrame);
206
207
  /**
208
   * Insert aFrame right after aPrevSibling, or prepend it to this
209
   * list if aPrevSibling is null. If aParent is not null, also
210
   * reparents newly-added frame. Note that this method always
211
   * sets the frame's nextSibling pointer.
212
   */
213
  void InsertFrame(nsContainerFrame* aParent, nsIFrame* aPrevSibling,
214
0
                   nsIFrame* aFrame) {
215
0
    nsFrameList temp(aFrame, aFrame);
216
0
    InsertFrames(aParent, aPrevSibling, temp);
217
0
  }
218
219
220
  /**
221
   * Inserts aFrameList into this list after aPrevSibling (at the beginning if
222
   * aPrevSibling is null).  If aParent is not null, reparents the newly added
223
   * frames.  Clears out aFrameList and returns a list slice representing the
224
   * newly-inserted frames.
225
   */
226
  Slice InsertFrames(nsContainerFrame* aParent, nsIFrame* aPrevSibling,
227
                     nsFrameList& aFrameList);
228
229
  class FrameLinkEnumerator;
230
231
  /**
232
   * Split this list just before the first frame that matches aPredicate,
233
   * and return a nsFrameList containing all the frames before it. The
234
   * matched frame and all frames after it stay in this list. If no matched
235
   * frame exists, all the frames are drained into the returned list, and
236
   * this list ends up empty.
237
   *
238
   * aPredicate should be of this function signature: bool(nsIFrame*).
239
   */
240
  template<typename Predicate>
241
0
  nsFrameList Split(Predicate&& aPredicate) {
242
0
    static_assert(
243
0
      std::is_same<typename mozilla::FunctionTypeTraits<Predicate>::ReturnType,
244
0
                   bool>::value &&
245
0
      mozilla::FunctionTypeTraits<Predicate>::arity == 1 &&
246
0
      std::is_same<typename mozilla::FunctionTypeTraits<Predicate>::template ParameterType<0>,
247
0
                   nsIFrame*>::value,
248
0
      "aPredicate should be of this function signature: bool(nsIFrame*)");
249
0
250
0
    FrameLinkEnumerator link(*this);
251
0
    link.Find(aPredicate);
252
0
    return ExtractHead(link);
253
0
  }
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:nsFrameList nsFrameList::Split<nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState&, nsContainerFrame*, nsFrameItems&, nsIFrame*, bool)::$_3>(nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState&, nsContainerFrame*, nsFrameItems&, nsIFrame*, bool)::$_3&&)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:nsFrameList nsFrameList::Split<nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState&, nsContainerFrame*, nsFrameItems&, nsIFrame*, bool)::$_4>(nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState&, nsContainerFrame*, nsFrameItems&, nsIFrame*, bool)::$_4&&)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:nsFrameList nsFrameList::Split<nsCSSFrameConstructor::WrapFramesInFirstLineFrame(nsFrameConstructorState&, nsIContent*, nsContainerFrame*, nsFirstLineFrame*, nsFrameItems&)::$_7>(nsCSSFrameConstructor::WrapFramesInFirstLineFrame(nsFrameConstructorState&, nsIContent*, nsContainerFrame*, nsFirstLineFrame*, nsFrameItems&)::$_7&&)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:nsFrameList nsFrameList::Split<nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState&, nsContainerFrame*, bool, nsFrameItems&, nsFrameItems&)::$_9>(nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState&, nsContainerFrame*, bool, nsFrameItems&, nsFrameItems&)::$_9&&)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:nsFrameList nsFrameList::Split<nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState&, nsContainerFrame*, bool, nsFrameItems&, nsFrameItems&)::$_10>(nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState&, nsContainerFrame*, bool, nsFrameItems&, nsFrameItems&)::$_10&&)
254
255
  /**
256
   * Split this frame list such that all the frames before the link pointed to
257
   * by aLink end up in the returned list, while the remaining frames stay in
258
   * this list.  After this call, aLink points to the beginning of this list.
259
   */
260
  nsFrameList ExtractHead(FrameLinkEnumerator& aLink);
261
262
  /**
263
   * Split this frame list such that all the frames coming after the link
264
   * pointed to by aLink end up in the returned list, while the frames before
265
   * that link stay in this list.  After this call, aLink is at end.
266
   */
267
  nsFrameList ExtractTail(FrameLinkEnumerator& aLink);
268
269
0
  nsIFrame* FirstChild() const {
270
0
    return mFirstChild;
271
0
  }
272
273
0
  nsIFrame* LastChild() const {
274
0
    return mLastChild;
275
0
  }
276
277
  nsIFrame* FrameAt(int32_t aIndex) const;
278
  int32_t IndexOf(nsIFrame* aFrame) const;
279
280
0
  bool IsEmpty() const {
281
0
    return nullptr == mFirstChild;
282
0
  }
283
284
0
  bool NotEmpty() const {
285
0
    return nullptr != mFirstChild;
286
0
  }
287
288
  bool ContainsFrame(const nsIFrame* aFrame) const;
289
290
  /**
291
   * Get the number of frames in this list. Note that currently the
292
   * implementation has O(n) time complexity. Do not call it repeatedly in hot
293
   * code.
294
   */
295
  int32_t GetLength() const;
296
297
  /**
298
   * If this frame list has only one frame, return that frame.
299
   * Otherwise, return null.
300
   */
301
0
  nsIFrame* OnlyChild() const {
302
0
    if (FirstChild() == LastChild()) {
303
0
      return FirstChild();
304
0
    }
305
0
    return nullptr;
306
0
  }
307
308
  /**
309
   * Call SetParent(aParent) for each frame in this list.
310
   * @param aParent the new parent frame, must be non-null
311
   */
312
  void ApplySetParent(nsContainerFrame* aParent) const;
313
314
  /**
315
   * If this frame list is non-empty then append it to aLists as the
316
   * aListID child list.
317
   * (this method is implemented in FrameChildList.h for dependency reasons)
318
   */
319
  inline void AppendIfNonempty(nsTArray<mozilla::layout::FrameChildList>* aLists,
320
                               mozilla::layout::FrameChildListID aListID) const;
321
322
  /**
323
   * Return the frame before this frame in visual order (after Bidi reordering).
324
   * If aFrame is null, return the last frame in visual order.
325
   */
326
  nsIFrame* GetPrevVisualFor(nsIFrame* aFrame) const;
327
328
  /**
329
   * Return the frame after this frame in visual order (after Bidi reordering).
330
   * If aFrame is null, return the first frame in visual order.
331
   */
332
  nsIFrame* GetNextVisualFor(nsIFrame* aFrame) const;
333
334
#ifdef DEBUG_FRAME_DUMP
335
  void List(FILE* out) const;
336
#endif
337
338
  static inline const nsFrameList& EmptyList();
339
340
  class Enumerator;
341
342
  /**
343
   * A class representing a slice of a frame list.
344
   */
345
  class Slice {
346
    friend class Enumerator;
347
348
  public:
349
    // Implicit on purpose, so that we can easily create enumerators from
350
    // nsFrameList via this impicit constructor.
351
    MOZ_IMPLICIT Slice(const nsFrameList& aList) :
352
#ifdef DEBUG
353
      mList(aList),
354
#endif
355
      mStart(aList.FirstChild()),
356
      mEnd(nullptr)
357
0
    {}
358
359
    Slice(const nsFrameList& aList, nsIFrame* aStart, nsIFrame* aEnd) :
360
#ifdef DEBUG
361
      mList(aList),
362
#endif
363
      mStart(aStart),
364
      mEnd(aEnd)
365
0
    {}
366
367
    Slice(const Slice& aOther) :
368
#ifdef DEBUG
369
      mList(aOther.mList),
370
#endif
371
      mStart(aOther.mStart),
372
      mEnd(aOther.mEnd)
373
    {}
374
375
  private:
376
#ifdef DEBUG
377
    const nsFrameList& mList;
378
#endif
379
    nsIFrame* const mStart; // our starting frame
380
    const nsIFrame* const mEnd; // The first frame that is NOT in the slice.
381
                                // May be null.
382
  };
383
384
  class Enumerator {
385
  public:
386
    explicit Enumerator(const Slice& aSlice) :
387
#ifdef DEBUG
388
      mSlice(aSlice),
389
#endif
390
      mFrame(aSlice.mStart),
391
      mEnd(aSlice.mEnd)
392
0
    {}
393
394
    Enumerator(const Enumerator& aOther) :
395
#ifdef DEBUG
396
      mSlice(aOther.mSlice),
397
#endif
398
      mFrame(aOther.mFrame),
399
      mEnd(aOther.mEnd)
400
    {}
401
402
0
    bool AtEnd() const {
403
0
      // Can't just check mEnd, because some table code goes and destroys the
404
0
      // tail of the frame list (including mEnd!) while iterating over the
405
0
      // frame list.
406
0
      return !mFrame || mFrame == mEnd;
407
0
    }
408
409
    /* Next() needs to know about nsIFrame, and nsIFrame will need to
410
       know about nsFrameList methods, so in order to inline this put
411
       the implementation in nsIFrame.h */
412
    inline void Next();
413
414
    /**
415
     * Get the current frame we're pointing to.  Do not call this on an
416
     * iterator that is at end!
417
     */
418
0
    nsIFrame* get() const {
419
0
      MOZ_ASSERT(!AtEnd(), "Enumerator is at end");
420
0
      return mFrame;
421
0
    }
422
423
    /**
424
     * Get an enumerator that is just like this one, but not limited in terms of
425
     * the part of the list it will traverse.
426
     */
427
0
    Enumerator GetUnlimitedEnumerator() const {
428
0
      return Enumerator(*this, nullptr);
429
0
    }
430
431
#ifdef DEBUG
432
    const nsFrameList& List() const { return mSlice.mList; }
433
#endif
434
435
  protected:
436
    Enumerator(const Enumerator& aOther, const nsIFrame* const aNewEnd):
437
#ifdef DEBUG
438
      mSlice(aOther.mSlice),
439
#endif
440
      mFrame(aOther.mFrame),
441
      mEnd(aNewEnd)
442
0
    {}
443
444
#ifdef DEBUG
445
    /* Has to be an object, not a reference, since the slice could
446
       well be a temporary constructed from an nsFrameList */
447
    const Slice mSlice;
448
#endif
449
    nsIFrame* mFrame; // our current frame.
450
    const nsIFrame* const mEnd; // The first frame we should NOT enumerate.
451
                                // May be null.
452
  };
453
454
  /**
455
   * A class that can be used to enumerate links between frames.  When created
456
   * from an nsFrameList, it points to the "link" immediately before the first
457
   * frame.  It can then be advanced until it points to the "link" immediately
458
   * after the last frame.  At any position, PrevFrame() and NextFrame() are
459
   * the frames before and after the given link.  This means PrevFrame() is
460
   * null when the enumerator is at the beginning of the list and NextFrame()
461
   * is null when it's AtEnd().
462
   */
463
  class FrameLinkEnumerator : private Enumerator {
464
  public:
465
    friend class nsFrameList;
466
467
    explicit FrameLinkEnumerator(const nsFrameList& aList) :
468
      Enumerator(aList),
469
      mPrev(nullptr)
470
0
    {}
471
472
    FrameLinkEnumerator(const FrameLinkEnumerator& aOther) :
473
      Enumerator(aOther),
474
      mPrev(aOther.mPrev)
475
    {}
476
477
    /* This constructor needs to know about nsIFrame, and nsIFrame will need to
478
       know about nsFrameList methods, so in order to inline this put
479
       the implementation in nsIFrame.h */
480
    inline FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame);
481
482
    void operator=(const FrameLinkEnumerator& aOther) {
483
      MOZ_ASSERT(&List() == &aOther.List(), "Different lists?");
484
      mFrame = aOther.mFrame;
485
      mPrev = aOther.mPrev;
486
    }
487
488
    inline void Next();
489
490
    /**
491
     * Find the first frame from the current position that satisfies
492
     * aPredicate, and stop at it. If no such frame exists, then this method
493
     * advances to the end of the list.
494
     *
495
     * aPredicate should be of this function signature: bool(nsIFrame*).
496
     *
497
     * Note: Find() needs to see the definition of Next(), so put this
498
     * definition in nsIFrame.h.
499
     */
500
    template<typename Predicate>
501
    inline void Find(Predicate&& aPredicate);
502
503
0
    bool AtEnd() const { return Enumerator::AtEnd(); }
504
505
0
    nsIFrame* PrevFrame() const { return mPrev; }
506
0
    nsIFrame* NextFrame() const { return mFrame; }
507
508
  protected:
509
    nsIFrame* mPrev;
510
  };
511
512
  class Iterator
513
  {
514
  public:
515
    Iterator(const nsFrameList& aList, nsIFrame* aCurrent)
516
      : mList(aList)
517
      , mCurrent(aCurrent)
518
0
    {}
519
520
    Iterator(const Iterator& aOther)
521
      : mList(aOther.mList)
522
      , mCurrent(aOther.mCurrent)
523
0
    {}
524
525
0
    nsIFrame* operator*() const { return mCurrent; }
526
527
    // The operators need to know about nsIFrame, hence the
528
    // implementations are in nsIFrame.h
529
    Iterator& operator++();
530
    Iterator& operator--();
531
532
    Iterator operator++(int) { auto ret = *this; ++*this; return ret; }
533
    Iterator operator--(int) { auto ret = *this; --*this; return ret; }
534
535
    friend bool operator==(const Iterator& aIter1, const Iterator& aIter2);
536
    friend bool operator!=(const Iterator& aIter1, const Iterator& aIter2);
537
538
  private:
539
    const nsFrameList& mList;
540
    nsIFrame* mCurrent;
541
  };
542
543
  typedef Iterator iterator;
544
  typedef Iterator const_iterator;
545
  typedef mozilla::ReverseIterator<Iterator> reverse_iterator;
546
  typedef mozilla::ReverseIterator<Iterator> const_reverse_iterator;
547
548
0
  iterator begin() const { return iterator(*this, mFirstChild); }
549
  const_iterator cbegin() const { return begin(); }
550
0
  iterator end() const { return iterator(*this, nullptr); }
551
  const_iterator cend() const { return end(); }
552
0
  reverse_iterator rbegin() const { return reverse_iterator(end()); }
553
  const_reverse_iterator crbegin() const { return rbegin(); }
554
0
  reverse_iterator rend() const { return reverse_iterator(begin()); }
555
  const_reverse_iterator crend() const { return rend(); }
556
557
private:
558
  void operator delete(void*) = delete;
559
560
#ifdef DEBUG_FRAME_LIST
561
  void VerifyList() const;
562
#else
563
0
  void VerifyList() const {}
564
#endif
565
566
protected:
567
  /**
568
   * Disconnect aFrame from its siblings.  This must only be called if aFrame
569
   * is NOT the first or last sibling, because otherwise its nsFrameList will
570
   * have a stale mFirst/LastChild pointer.  This precondition is asserted.
571
   * This function is O(1).
572
   */
573
  static void UnhookFrameFromSiblings(nsIFrame* aFrame);
574
575
  nsIFrame* mFirstChild;
576
  nsIFrame* mLastChild;
577
};
578
579
inline bool
580
operator==(const nsFrameList::Iterator& aIter1,
581
           const nsFrameList::Iterator& aIter2)
582
0
{
583
0
  MOZ_ASSERT(&aIter1.mList == &aIter2.mList,
584
0
             "must not compare iterator from different list");
585
0
  return aIter1.mCurrent == aIter2.mCurrent;
586
0
}
587
588
inline bool
589
operator!=(const nsFrameList::Iterator& aIter1,
590
           const nsFrameList::Iterator& aIter2)
591
0
{
592
0
  MOZ_ASSERT(&aIter1.mList == &aIter2.mList,
593
0
             "Must not compare iterator from different list");
594
0
  return aIter1.mCurrent != aIter2.mCurrent;
595
0
}
596
597
namespace mozilla {
598
namespace layout {
599
600
/**
601
 * Simple "auto_ptr" for nsFrameLists allocated from the shell arena.
602
 * The frame list given to the constructor will be deallocated (if non-null)
603
 * in the destructor.  The frame list must then be empty.
604
 */
605
class AutoFrameListPtr {
606
public:
607
  AutoFrameListPtr(nsPresContext* aPresContext, nsFrameList* aFrameList)
608
0
    : mPresContext(aPresContext), mFrameList(aFrameList) {}
609
  ~AutoFrameListPtr();
610
0
  operator nsFrameList*() const { return mFrameList; }
611
0
  nsFrameList* operator->() const { return mFrameList; }
612
private:
613
  nsPresContext* mPresContext;
614
  nsFrameList* mFrameList;
615
};
616
617
namespace detail {
618
union AlignedFrameListBytes {
619
  void* ptr;
620
  char bytes[sizeof(nsFrameList)];
621
};
622
extern const AlignedFrameListBytes gEmptyFrameListBytes;
623
} // namespace detail
624
625
} // namespace layout
626
} // namespace mozilla
627
628
/* static */ inline const nsFrameList&
629
nsFrameList::EmptyList()
630
0
{
631
0
  return *reinterpret_cast<const nsFrameList*>(&mozilla::layout::detail::gEmptyFrameListBytes);
632
0
}
633
634
#endif /* nsFrameList_h___ */