Diff
Modified: trunk/Source/WebCore/ChangeLog (231092 => 231093)
--- trunk/Source/WebCore/ChangeLog 2018-04-27 11:47:37 UTC (rev 231092)
+++ trunk/Source/WebCore/ChangeLog 2018-04-27 14:34:47 UTC (rev 231093)
@@ -1,3 +1,52 @@
+2018-04-27 Zalan Bujtas <[email protected]>
+
+ [LFC] Add layout tree iterators.
+ https://bugs.webkit.org/show_bug.cgi?id=185058
+
+ Reviewed by Antti Koivisto.
+
+ They work exactly like the renderer tree iterators.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * layout/layouttree/LayoutAncestorIterator.h: Added.
+ (WebCore::Layout::LayoutAncestorIterator<T>::LayoutAncestorIterator):
+ (WebCore::Layout::LayoutAncestorIterator<T>::operator):
+ (WebCore::Layout::LayoutAncestorIteratorAdapter<T>::LayoutAncestorIteratorAdapter):
+ (WebCore::Layout::LayoutAncestorIteratorAdapter<T>::begin const):
+ (WebCore::Layout::LayoutAncestorIteratorAdapter<T>::end const):
+ (WebCore::Layout::LayoutAncestorIteratorAdapter<T>::first const):
+ (WebCore::Layout::ancestorsOfType):
+ (WebCore::Layout::lineageOfType):
+ * layout/layouttree/LayoutBox.cpp:
+ * layout/layouttree/LayoutChildIterator.h: Added.
+ (WebCore::Layout::LayoutChildtIterator<T>::LayoutChildtIterator):
+ (WebCore::Layout::LayoutChildtIterator<T>::operator):
+ (WebCore::Layout::LayoutChildtIteratorAdapter<T>::LayoutChildtIteratorAdapter):
+ (WebCore::Layout::LayoutChildtIteratorAdapter<T>::begin const):
+ (WebCore::Layout::LayoutChildtIteratorAdapter<T>::end const):
+ (WebCore::Layout::LayoutChildtIteratorAdapter<T>::first const):
+ (WebCore::Layout::LayoutChildtIteratorAdapter<T>::last const):
+ (WebCore::Layout::childrenOfType):
+ * layout/layouttree/LayoutIterator.h: Added.
+ (WebCore::Layout::isLayoutBoxOfType):
+ (WebCore::Layout::Traversal::firstChild):
+ (WebCore::Layout::Traversal::lastChild):
+ (WebCore::Layout::Traversal::nextSibling):
+ (WebCore::Layout::Traversal::previousSibling):
+ (WebCore::Layout::Traversal::findAncestorOfType):
+ (WebCore::Layout::Traversal::nextAncestorSibling):
+ (WebCore::Layout::Traversal::nextWithin):
+ (WebCore::Layout::Traversal::firstWithin):
+ (WebCore::Layout::Traversal::next):
+ (WebCore::Layout::LayoutIterator<T>::LayoutIterator):
+ (WebCore::Layout::LayoutIterator<T>::traverseNextSibling):
+ (WebCore::Layout::LayoutIterator<T>::traverseNext):
+ (WebCore::Layout::LayoutIterator<T>::traversePreviousSibling):
+ (WebCore::Layout::LayoutIterator<T>::traverseAncestor):
+ (WebCore::Layout::LayoutIterator<T>::operator const):
+ (WebCore::Layout:: const):
+ (WebCore::Layout::= const):
+
2018-04-27 Commit Queue <[email protected]>
Unreviewed, rolling out r231089.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (231092 => 231093)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-04-27 11:47:37 UTC (rev 231092)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-04-27 14:34:47 UTC (rev 231093)
@@ -5717,6 +5717,9 @@
0FFD4D5F18651FA300512F6E /* AsyncScrollingCoordinator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncScrollingCoordinator.h; sourceTree = "<group>"; };
10FB084A14E15C7E00A3DB98 /* PublicURLManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PublicURLManager.h; sourceTree = "<group>"; };
1100FC6E1FDB3C4D00DD961B /* TrailingFloatsRootInlineBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TrailingFloatsRootInlineBox.cpp; sourceTree = "<group>"; };
+ 11100FC72092764C0081AA6C /* LayoutIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutIterator.h; sourceTree = "<group>"; };
+ 11100FC920927CBC0081AA6C /* LayoutChildIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutChildIterator.h; sourceTree = "<group>"; };
+ 11100FCA2092868D0081AA6C /* LayoutAncestorIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutAncestorIterator.h; sourceTree = "<group>"; };
112B34D01E60B8A700BB310A /* SimpleLineLayoutPagination.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutPagination.cpp; sourceTree = "<group>"; };
112B34D41E60B98300BB310A /* SimpleLineLayoutPagination.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutPagination.h; sourceTree = "<group>"; };
113409D7203E038000C66915 /* RenderTreeBuilderContinuation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderContinuation.cpp; sourceTree = "<group>"; };
@@ -15655,10 +15658,12 @@
115CFA90208B9441001E6991 /* layouttree */ = {
isa = PBXGroup;
children = (
+ 11100FCA2092868D0081AA6C /* LayoutAncestorIterator.h */,
1199FA4A208E37B6002358CC /* LayoutBlockContainer.cpp */,
1199FA49208E37B6002358CC /* LayoutBlockContainer.h */,
115CFA96208B952B001E6991 /* LayoutBox.cpp */,
115CFA95208B952B001E6991 /* LayoutBox.h */,
+ 11100FC920927CBC0081AA6C /* LayoutChildIterator.h */,
1199FA45208E35A3002358CC /* LayoutContainer.cpp */,
1199FA44208E35A3002358CC /* LayoutContainer.h */,
1199FA52208E38D3002358CC /* LayoutInlineBox.cpp */,
@@ -15665,6 +15670,7 @@
1199FA51208E38D3002358CC /* LayoutInlineBox.h */,
1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */,
1199FA4D208E3899002358CC /* LayoutInlineContainer.h */,
+ 11100FC72092764C0081AA6C /* LayoutIterator.h */,
);
path = layouttree;
sourceTree = "<group>";
@@ -27851,6 +27857,7 @@
C4CD629B18383766007EBAF1 /* FrameSnapshotting.h in Headers */,
65A21485097A3F5300B9050A /* FrameTree.h in Headers */,
65CBFEFA0974F607001DAC25 /* FrameView.h in Headers */,
+ 113D0B521F9FDD2B00F611BB /* FrameViewLayoutContext.h in Headers */,
97205AB0123928CA00B17380 /* FTPDirectoryDocument.h in Headers */,
51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */,
26B999931803B9D900D01121 /* FunctionCall.h in Headers */,
@@ -29105,7 +29112,6 @@
1199FA4B208E37B6002358CC /* LayoutBlockContainer.h in Headers */,
115CFA97208B952B001E6991 /* LayoutBox.h in Headers */,
1199FA46208E35A3002358CC /* LayoutContainer.h in Headers */,
- 113D0B521F9FDD2B00F611BB /* FrameViewLayoutContext.h in Headers */,
6F7CA3C6208C2957002F29AB /* LayoutContext.h in Headers */,
1199FA53208E38D3002358CC /* LayoutInlineBox.h in Headers */,
1199FA4F208E3899002358CC /* LayoutInlineContainer.h in Headers */,
Added: trunk/Source/WebCore/layout/layouttree/LayoutAncestorIterator.h (0 => 231093)
--- trunk/Source/WebCore/layout/layouttree/LayoutAncestorIterator.h (rev 0)
+++ trunk/Source/WebCore/layout/layouttree/LayoutAncestorIterator.h 2018-04-27 14:34:47 UTC (rev 231093)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "LayoutIterator.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+template <typename T>
+class LayoutAncestorIterator : public LayoutIterator<T> {
+public:
+ LayoutAncestorIterator();
+ explicit LayoutAncestorIterator(const T* current);
+ LayoutAncestorIterator& operator++();
+};
+
+template <typename T>
+class LayoutAncestorIteratorAdapter {
+public:
+ LayoutAncestorIteratorAdapter(const T* first);
+ LayoutAncestorIterator<T> begin() const;
+ LayoutAncestorIterator<T> end() const;
+ const T* first() const;
+
+private:
+ const T* m_first;
+};
+
+template <typename T> LayoutAncestorIteratorAdapter<T> ancestorsOfType(const Box&);
+template <typename T> LayoutAncestorIteratorAdapter<T> lineageOfType(const Box&);
+
+// LayoutAncestorIterator
+
+template <typename T>
+inline LayoutAncestorIterator<T>::LayoutAncestorIterator()
+ : LayoutIterator<T>(nullptr)
+{
+}
+
+template <typename T>
+inline LayoutAncestorIterator<T>::LayoutAncestorIterator(const T* current)
+ : LayoutIterator<T>(nullptr, current)
+{
+}
+
+template <typename T>
+inline LayoutAncestorIterator<T>& LayoutAncestorIterator<T>::operator++()
+{
+ return static_cast<LayoutAncestorIterator<T>&>(LayoutIterator<T>::traverseAncestor());
+}
+
+// LayoutAncestorIteratorAdapter
+
+template <typename T>
+inline LayoutAncestorIteratorAdapter<T>::LayoutAncestorIteratorAdapter(const T* first)
+ : m_first(first)
+{
+}
+
+template <typename T>
+inline LayoutAncestorIterator<T> LayoutAncestorIteratorAdapter<T>::begin() const
+{
+ return LayoutAncestorIterator<T>(m_first);
+}
+
+template <typename T>
+inline LayoutAncestorIterator<T> LayoutAncestorIteratorAdapter<T>::end() const
+{
+ return LayoutAncestorIterator<T>();
+}
+
+template <typename T>
+inline const T* LayoutAncestorIteratorAdapter<T>::first() const
+{
+ return m_first;
+}
+
+// Standalone functions
+
+template <typename T>
+inline LayoutAncestorIteratorAdapter<T> ancestorsOfType(const Box& descendant)
+{
+ const T* first = Traversal::findAncestorOfType<const T>(descendant);
+ return LayoutAncestorIteratorAdapter<T>(first);
+}
+
+template <typename T>
+inline LayoutAncestorIteratorAdapter<T> lineageOfType(const Box& first)
+{
+ if (isLayoutBoxOfType<T>(first))
+ return LayoutAncestorIteratorAdapter<T>(static_cast<const T*>(&first));
+ return ancestorsOfType<T>(first);
+}
+
+}
+}
+#endif
Added: trunk/Source/WebCore/layout/layouttree/LayoutChildIterator.h (0 => 231093)
--- trunk/Source/WebCore/layout/layouttree/LayoutChildIterator.h (rev 0)
+++ trunk/Source/WebCore/layout/layouttree/LayoutChildIterator.h 2018-04-27 14:34:47 UTC (rev 231093)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "LayoutIterator.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+template <typename T>
+class LayoutChildtIterator : public LayoutIterator<T> {
+public:
+ LayoutChildtIterator(const Container& parent);
+ LayoutChildtIterator(const Container& parent, const T* current);
+ LayoutChildtIterator& operator++();
+};
+
+template <typename T>
+class LayoutChildtIteratorAdapter {
+public:
+ LayoutChildtIteratorAdapter(const Container& parent);
+ LayoutChildtIterator<T> begin() const;
+ LayoutChildtIterator<T> end() const;
+ const T* first() const;
+ const T* last() const;
+
+private:
+ const Container& m_parent;
+};
+
+template <typename T> LayoutChildtIteratorAdapter<T> childrenOfType(const Container&);
+
+// LayoutChildtIterator
+
+template <typename T>
+inline LayoutChildtIterator<T>::LayoutChildtIterator(const Container& parent)
+ : LayoutIterator<T>(&parent)
+{
+}
+
+template <typename T>
+inline LayoutChildtIterator<T>::LayoutChildtIterator(const Container& parent, const T* current)
+ : LayoutIterator<T>(&parent, current)
+{
+}
+
+template <typename T>
+inline LayoutChildtIterator<T>& LayoutChildtIterator<T>::operator++()
+{
+ return static_cast<LayoutChildtIterator<T>&>(LayoutIterator<T>::traverseNextSibling());
+}
+
+// LayoutChildtIteratorAdapter
+
+template <typename T>
+inline LayoutChildtIteratorAdapter<T>::LayoutChildtIteratorAdapter(const Container& parent)
+ : m_parent(parent)
+{
+}
+
+template <typename T>
+inline LayoutChildtIterator<T> LayoutChildtIteratorAdapter<T>::begin() const
+{
+ return LayoutChildtIterator<T>(m_parent, Traversal::firstChild<T>(m_parent));
+}
+
+template <typename T>
+inline LayoutChildtIterator<T> LayoutChildtIteratorAdapter<T>::end() const
+{
+ return LayoutChildtIterator<T>(m_parent);
+}
+
+template <typename T>
+inline const T* LayoutChildtIteratorAdapter<T>::first() const
+{
+ return Traversal::firstChild<T>(m_parent);
+}
+
+template <typename T>
+inline const T* LayoutChildtIteratorAdapter<T>::last() const
+{
+ return Traversal::lastChild<T>(m_parent);
+}
+
+template <typename T>
+inline LayoutChildtIteratorAdapter<T> childrenOfType(const Container& parent)
+{
+ return LayoutChildtIteratorAdapter<T>(parent);
+}
+
+}
+}
+#endif
Added: trunk/Source/WebCore/layout/layouttree/LayoutIterator.h (0 => 231093)
--- trunk/Source/WebCore/layout/layouttree/LayoutIterator.h (rev 0)
+++ trunk/Source/WebCore/layout/layouttree/LayoutIterator.h 2018-04-27 14:34:47 UTC (rev 231093)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+template <typename T>
+class LayoutIterator {
+public:
+ LayoutIterator(const Container* root);
+ LayoutIterator(const Container* root, const T* current);
+
+ const T& operator*() const;
+ const T* operator->() const;
+
+ bool operator==(const LayoutIterator& other) const;
+ bool operator!=(const LayoutIterator& other) const;
+
+ LayoutIterator& traverseNext();
+ LayoutIterator& traverseNextSibling();
+ LayoutIterator& traversePreviousSibling();
+ LayoutIterator& traverseAncestor();
+
+private:
+ const Container* m_root;
+ const T* m_current;
+};
+
+// Similar to WTF::is<>() but without the static_assert() making sure the check is necessary.
+template <typename T, typename U>
+inline bool isLayoutBoxOfType(const U& layoutBox) { return TypeCastTraits<const T, const U>::isOfType(layoutBox); }
+
+// Traversal helpers
+namespace Traversal {
+
+template <typename T, typename U>
+inline const T* firstChild(U& current)
+{
+ auto* object = current.firstChild();
+ while (object && !isLayoutBoxOfType<T>(*object))
+ object = object->nextSibling();
+ return static_cast<const T*>(object);
+}
+
+template <typename T, typename U>
+inline const T* lastChild(U& current)
+{
+ auto* object = current.lastChild();
+ while (object && !isLayoutBoxOfType<T>(*object))
+ object = object->previousSibling();
+ return static_cast<const T*>(object);
+}
+
+template <typename T, typename U>
+inline const T* nextSibling(U& current)
+{
+ auto* object = current.nextSibling();
+ while (object && !isLayoutBoxOfType<T>(*object))
+ object = object->nextSibling();
+ return static_cast<const T*>(object);
+}
+
+template <typename T, typename U>
+inline const T* previousSibling(U& current)
+{
+ auto* object = current.previousSibling();
+ while (object && !isLayoutBoxOfType<T>(*object))
+ object = object->previousSibling();
+ return static_cast<const T*>(object);
+}
+
+template <typename T>
+inline const T* findAncestorOfType(const Box& current)
+{
+ for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
+ if (isLayoutBoxOfType<T>(*ancestor))
+ return static_cast<const T*>(ancestor);
+ }
+ return nullptr;
+}
+
+template <typename T, typename U>
+inline const T* nextAncestorSibling(U& current, const Container* stayWithin)
+{
+ for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
+ if (ancestor == stayWithin)
+ return nullptr;
+ if (auto* sibling = ancestor->nextSibling())
+ return sibling;
+ }
+ return nullptr;
+}
+
+template <typename T, typename U>
+inline const T* nextWithin(U& current, const Container* stayWithin)
+{
+ if (auto* child = firstChild(current))
+ return child;
+
+ if (¤t == stayWithin)
+ return nullptr;
+
+ if (auto* sibling = current.nextSibling())
+ return sibling;
+
+ return nextAncestorSibling(current, stayWithin);
+}
+
+template <typename T, typename U>
+inline const T* firstWithin(U& current)
+{
+ auto* descendant = current.fistChild();
+ while (descendant && !isLayoutBoxOfType<T>(*descendant))
+ descendant = nextWithin(*descendant, ¤t);
+ return static_cast<const T*>(descendant);
+}
+
+template <typename T, typename U>
+inline const T* next(U& current, const RenderObject* stayWithin)
+{
+ auto* descendant = nextWithin(current, stayWithin);
+ while (descendant && !isLayoutBoxOfType<T>(*descendant))
+ descendant = nextWithin(*descendant, stayWithin);
+ return static_cast<const T*>(descendant);
+}
+
+}
+
+// LayoutIterator
+
+template <typename T>
+inline LayoutIterator<T>::LayoutIterator(const Container* root)
+ : m_root(root)
+ , m_current(nullptr)
+{
+}
+
+template <typename T>
+inline LayoutIterator<T>::LayoutIterator(const Container* root, const T* current)
+ : m_root(root)
+ , m_current(current)
+{
+}
+
+template <typename T>
+inline LayoutIterator<T>& LayoutIterator<T>::traverseNextSibling()
+{
+ ASSERT(m_current);
+ m_current = Traversal::nextSibling<T>(*m_current);
+ return *this;
+}
+
+template <typename T>
+inline LayoutIterator<T>& LayoutIterator<T>::traverseNext()
+{
+ ASSERT(m_current);
+ m_current = Traversal::next<T>(*m_current, m_root);
+ return *this;
+}
+
+template <typename T>
+inline LayoutIterator<T>& LayoutIterator<T>::traversePreviousSibling()
+{
+ ASSERT(m_current);
+ m_current = Traversal::previousSibling<T>(m_current);
+ return *this;
+}
+
+
+template <typename T>
+inline LayoutIterator<T>& LayoutIterator<T>::traverseAncestor()
+{
+ ASSERT(m_current);
+ ASSERT(m_current != m_root);
+ m_current = Traversal::findAncestorOfType<const T>(*m_current);
+ return *this;
+}
+
+template <typename T>
+inline const T& LayoutIterator<T>::operator*() const
+{
+ ASSERT(m_current);
+ return *m_current;
+}
+
+template <typename T>
+inline const T* LayoutIterator<T>::operator->() const
+{
+ ASSERT(m_current);
+ return m_current;
+}
+
+template <typename T>
+inline bool LayoutIterator<T>::operator==(const LayoutIterator& other) const
+{
+ ASSERT(m_root == other.m_root);
+ return m_current == other.m_current;
+}
+
+template <typename T>
+inline bool LayoutIterator<T>::operator!=(const LayoutIterator& other) const
+{
+ return !(*this == other);
+}
+
+}
+}
+#include "LayoutAncestorIterator.h"
+#include "LayoutChildIterator.h"
+
+#endif