WebCore should build successfully even with -DENABLE_UNIFIED_BUILDS=OFF
[WebKit-https.git] / Source / WebCore / rendering / RenderIterator.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "RenderElement.h"
29
30 namespace WebCore {
31
32 class RenderText;
33
34 template <typename T>
35 class RenderIterator {
36 public:
37     RenderIterator(const RenderElement* root);
38     RenderIterator(const RenderElement* root, T* current);
39
40     T& operator*();
41     T* operator->();
42
43     bool operator==(const RenderIterator& other) const;
44     bool operator!=(const RenderIterator& other) const;
45
46     RenderIterator& traverseNext();
47     RenderIterator& traverseNextSibling();
48     RenderIterator& traversePreviousSibling();
49     RenderIterator& traverseAncestor();
50
51 private:
52     const RenderElement* m_root;
53     T* m_current;
54 };
55
56 template <typename T>
57 class RenderConstIterator {
58 public:
59     RenderConstIterator(const RenderElement* root);
60     RenderConstIterator(const RenderElement* root, const T* current);
61
62     const T& operator*() const;
63     const T* operator->() const;
64
65     bool operator==(const RenderConstIterator& other) const;
66     bool operator!=(const RenderConstIterator& other) const;
67
68     RenderConstIterator& traverseNext();
69     RenderConstIterator& traverseNextSibling();
70     RenderConstIterator& traversePreviousSibling();
71     RenderConstIterator& traverseAncestor();
72
73 private:
74     const RenderElement* m_root;
75     const T* m_current;
76 };
77
78 // Similar to WTF::is<>() but without the static_assert() making sure the check is necessary.
79 template <typename T, typename U>
80 inline bool isRendererOfType(const U& renderer) { return TypeCastTraits<const T, const U>::isOfType(renderer); }
81
82 // Traversal helpers
83
84 namespace RenderObjectTraversal {
85
86 template <typename U>
87 inline RenderObject* firstChild(U& object)
88 {
89     return object.firstChild();
90 }
91
92 inline RenderObject* firstChild(RenderObject& object)
93 {
94     return object.firstChildSlow();
95 }
96
97 inline RenderObject* firstChild(RenderText&)
98 {
99     return nullptr;
100 }
101
102 inline RenderObject* nextAncestorSibling(RenderObject& current, const RenderObject* stayWithin)
103 {
104     for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
105         if (ancestor == stayWithin)
106             return nullptr;
107         if (auto* sibling = ancestor->nextSibling())
108             return sibling;
109     }
110     return nullptr;
111 }
112
113 template <typename U>
114 inline RenderObject* next(U& current, const RenderObject* stayWithin)
115 {
116     if (auto* child = firstChild(current))
117         return child;
118
119     if (&current == stayWithin)
120         return nullptr;
121
122     if (auto* sibling = current.nextSibling())
123         return sibling;
124
125     return nextAncestorSibling(current, stayWithin);
126 }
127
128 inline RenderObject* nextSkippingChildren(RenderObject& current, const RenderObject* stayWithin)
129 {
130     if (&current == stayWithin)
131         return nullptr;
132
133     if (auto* sibling = current.nextSibling())
134         return sibling;
135
136     return nextAncestorSibling(current, stayWithin);
137 }
138
139 }
140
141 namespace RenderTraversal {
142
143 template <typename T, typename U>
144 inline T* firstChild(U& current)
145 {
146     RenderObject* object = RenderObjectTraversal::firstChild(current);
147     while (object && !isRendererOfType<T>(*object))
148         object = object->nextSibling();
149     return static_cast<T*>(object);
150 }
151
152 template <typename T, typename U>
153 inline T* lastChild(U& current)
154 {
155     RenderObject* object = current.lastChild();
156     while (object && !isRendererOfType<T>(*object))
157         object = object->previousSibling();
158     return static_cast<T*>(object);
159 }
160
161 template <typename T, typename U>
162 inline T* nextSibling(U& current)
163 {
164     RenderObject* object = current.nextSibling();
165     while (object && !isRendererOfType<T>(*object))
166         object = object->nextSibling();
167     return static_cast<T*>(object);
168 }
169
170 template <typename T, typename U>
171 inline T* previousSibling(U& current)
172 {
173     RenderObject* object = current.previousSibling();
174     while (object && !isRendererOfType<T>(*object))
175         object = object->previousSibling();
176     return static_cast<T*>(object);
177 }
178
179 template <typename T>
180 inline T* findAncestorOfType(const RenderObject& current)
181 {
182     for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
183         if (isRendererOfType<T>(*ancestor))
184             return static_cast<T*>(ancestor);
185     }
186     return nullptr;
187 }
188
189 template <typename T, typename U>
190 inline T* firstWithin(U& current)
191 {
192     auto* descendant = RenderObjectTraversal::firstChild(current);
193     while (descendant && !isRendererOfType<T>(*descendant))
194         descendant = RenderObjectTraversal::next(*descendant, &current);
195     return static_cast<T*>(descendant);
196 }
197
198 template <typename T, typename U>
199 inline T* next(U& current, const RenderObject* stayWithin)
200 {
201     auto* descendant = RenderObjectTraversal::next(current, stayWithin);
202     while (descendant && !isRendererOfType<T>(*descendant))
203         descendant = RenderObjectTraversal::next(*descendant, stayWithin);
204     return static_cast<T*>(descendant);
205 }
206
207 } // namespace WebCore::RenderTraversal
208
209 // RenderIterator
210
211 template <typename T>
212 inline RenderIterator<T>::RenderIterator(const RenderElement* root)
213     : m_root(root)
214     , m_current(nullptr)
215 {
216 }
217
218 template <typename T>
219 inline RenderIterator<T>::RenderIterator(const RenderElement* root, T* current)
220     : m_root(root)
221     , m_current(current)
222 {
223 }
224
225 template <typename T>
226 inline RenderIterator<T>& RenderIterator<T>::traverseNextSibling()
227 {
228     ASSERT(m_current);
229     m_current = RenderTraversal::nextSibling<T>(*m_current);
230     return *this;
231 }
232
233 template <typename T>
234 inline RenderIterator<T>& RenderIterator<T>::traverseNext()
235 {
236     ASSERT(m_current);
237     m_current = RenderTraversal::next<T>(*m_current, m_root);
238     return *this;
239 }
240
241 template <typename T>
242 inline RenderIterator<T>& RenderIterator<T>::traversePreviousSibling()
243 {
244     ASSERT(m_current);
245     m_current = RenderTraversal::previousSibling<T>(*m_current);
246     return *this;
247 }
248
249 template <typename T>
250 inline RenderIterator<T>& RenderIterator<T>::traverseAncestor()
251 {
252     ASSERT(m_current);
253     ASSERT(m_current != m_root);
254     m_current = RenderTraversal::findAncestorOfType<T>(*m_current);
255     return *this;
256 }
257
258 template <typename T>
259 inline T& RenderIterator<T>::operator*()
260 {
261     ASSERT(m_current);
262     return *m_current;
263 }
264
265 template <typename T>
266 inline T* RenderIterator<T>::operator->()
267 {
268     ASSERT(m_current);
269     return m_current;
270 }
271
272 template <typename T>
273 inline bool RenderIterator<T>::operator==(const RenderIterator& other) const
274 {
275     ASSERT(m_root == other.m_root);
276     return m_current == other.m_current;
277 }
278
279 template <typename T>
280 inline bool RenderIterator<T>::operator!=(const RenderIterator& other) const
281 {
282     return !(*this == other);
283 }
284
285 // RenderConstIterator
286
287 template <typename T>
288 inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root)
289     : m_root(root)
290     , m_current(nullptr)
291 {
292 }
293
294 template <typename T>
295 inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root, const T* current)
296     : m_root(root)
297     , m_current(current)
298 {
299 }
300
301 template <typename T>
302 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNextSibling()
303 {
304     ASSERT(m_current);
305     m_current = RenderTraversal::nextSibling<T>(*m_current);
306     return *this;
307 }
308
309 template <typename T>
310 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNext()
311 {
312     ASSERT(m_current);
313     m_current = RenderTraversal::next<T>(*m_current, m_root);
314     return *this;
315 }
316
317 template <typename T>
318 inline RenderConstIterator<T>& RenderConstIterator<T>::traversePreviousSibling()
319 {
320     ASSERT(m_current);
321     m_current = RenderTraversal::previousSibling<T>(m_current);
322     return *this;
323 }
324
325
326 template <typename T>
327 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseAncestor()
328 {
329     ASSERT(m_current);
330     ASSERT(m_current != m_root);
331     m_current = RenderTraversal::findAncestorOfType<const T>(*m_current);
332     return *this;
333 }
334
335 template <typename T>
336 inline const T& RenderConstIterator<T>::operator*() const
337 {
338     ASSERT(m_current);
339     return *m_current;
340 }
341
342 template <typename T>
343 inline const T* RenderConstIterator<T>::operator->() const
344 {
345     ASSERT(m_current);
346     return m_current;
347 }
348
349 template <typename T>
350 inline bool RenderConstIterator<T>::operator==(const RenderConstIterator& other) const
351 {
352     ASSERT(m_root == other.m_root);
353     return m_current == other.m_current;
354 }
355
356 template <typename T>
357 inline bool RenderConstIterator<T>::operator!=(const RenderConstIterator& other) const
358 {
359     return !(*this == other);
360 }
361
362 } // namespace WebCore
363
364 #include "RenderAncestorIterator.h"
365 #include "RenderChildIterator.h"