42680c5379e341ac3e82a2a68e8dae27029cd48e
[WebKit-https.git] / Source / WebCore / dom / ElementIterator.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 #ifndef ElementIterator_h
27 #define ElementIterator_h
28
29 #include "ElementTraversal.h"
30
31 #if !ASSERT_DISABLED
32 #include "ElementIteratorAssertions.h"
33 #endif
34
35 namespace WebCore {
36
37 template <typename ElementType>
38 class ElementIterator {
39 public:
40     ElementIterator(const ContainerNode* root);
41     ElementIterator(const ContainerNode* root, ElementType* current);
42
43     ElementType& operator*();
44     ElementType* operator->();
45
46     bool operator!=(const ElementIterator& other) const;
47
48     ElementIterator& traverseNext();
49     ElementIterator& traversePrevious();
50     ElementIterator& traverseNextSibling();
51     ElementIterator& traversePreviousSibling();
52
53 private:
54     const ContainerNode* m_root;
55     ElementType* m_current;
56
57 #if !ASSERT_DISABLED
58     ElementIteratorAssertions m_assertions;
59 #endif
60 };
61
62 template <typename ElementType>
63 class ElementConstIterator {
64 public:
65     ElementConstIterator(const ContainerNode* root);
66     ElementConstIterator(const ContainerNode* root, const ElementType* current);
67
68     const ElementType& operator*() const;
69     const ElementType* operator->() const;
70
71     bool operator!=(const ElementConstIterator& other) const;
72
73     ElementConstIterator& traverseNext();
74     ElementConstIterator& traversePrevious();
75     ElementConstIterator& traverseNextSibling();
76     ElementConstIterator& traversePreviousSibling();
77
78 private:
79     const ContainerNode* m_root;
80     const ElementType* m_current;
81
82 #if !ASSERT_DISABLED
83     ElementIteratorAssertions m_assertions;
84 #endif
85 };
86
87 // ElementIterator
88
89 template <typename ElementType>
90 inline ElementIterator<ElementType>::ElementIterator(const ContainerNode* root)
91     : m_root(root)
92     , m_current(nullptr)
93 {
94 }
95
96 template <typename ElementType>
97 inline ElementIterator<ElementType>::ElementIterator(const ContainerNode* root, ElementType* current)
98     : m_root(root)
99     , m_current(current)
100 #if !ASSERT_DISABLED
101     , m_assertions(current)
102 #endif
103 {
104 }
105
106 template <typename ElementType>
107 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseNext()
108 {
109     ASSERT(m_current);
110     ASSERT(!m_assertions.domTreeHasMutated());
111     m_current = Traversal<ElementType>::next(m_current, m_root);
112 #if !ASSERT_DISABLED
113     // Drop the assertion when the iterator reaches the end.
114     if (!m_current)
115         m_assertions.dropEventDispatchAssertion();
116 #endif
117     return *this;
118 }
119
120 template <typename ElementType>
121 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traversePrevious()
122 {
123     ASSERT(m_current);
124     ASSERT(!m_assertions.domTreeHasMutated());
125     m_current = Traversal<ElementType>::previous(m_current, m_root);
126 #if !ASSERT_DISABLED
127     // Drop the assertion when the iterator reaches the end.
128     if (!m_current)
129         m_assertions.dropEventDispatchAssertion();
130 #endif
131     return *this;
132 }
133
134 template <typename ElementType>
135 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseNextSibling()
136 {
137     ASSERT(m_current);
138     ASSERT(!m_assertions.domTreeHasMutated());
139     m_current = Traversal<ElementType>::nextSibling(m_current);
140 #if !ASSERT_DISABLED
141     // Drop the assertion when the iterator reaches the end.
142     if (!m_current)
143         m_assertions.dropEventDispatchAssertion();
144 #endif
145     return *this;
146 }
147
148 template <typename ElementType>
149 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traversePreviousSibling()
150 {
151     ASSERT(m_current);
152     ASSERT(!m_assertions.domTreeHasMutated());
153     m_current = Traversal<ElementType>::previousSibling(m_current);
154 #if !ASSERT_DISABLED
155     // Drop the assertion when the iterator reaches the end.
156     if (!m_current)
157         m_assertions.dropEventDispatchAssertion();
158 #endif
159     return *this;
160 }
161
162 template <typename ElementType>
163 inline ElementType& ElementIterator<ElementType>::operator*()
164 {
165     ASSERT(m_current);
166     ASSERT(!m_assertions.domTreeHasMutated());
167     return *m_current;
168 }
169
170 template <typename ElementType>
171 inline ElementType* ElementIterator<ElementType>::operator->()
172 {
173     ASSERT(m_current);
174     ASSERT(!m_assertions.domTreeHasMutated());
175     return m_current;
176 }
177
178 template <typename ElementType>
179 inline bool ElementIterator<ElementType>::operator!=(const ElementIterator& other) const
180 {
181     ASSERT(m_root == other.m_root);
182     ASSERT(!m_assertions.domTreeHasMutated());
183     return m_current != other.m_current;
184 }
185
186 // ElementConstIterator
187
188 template <typename ElementType>
189 inline ElementConstIterator<ElementType>::ElementConstIterator(const ContainerNode* root)
190     : m_root(root)
191     , m_current(nullptr)
192 {
193 }
194
195 template <typename ElementType>
196 inline ElementConstIterator<ElementType>::ElementConstIterator(const ContainerNode* root, const ElementType* current)
197     : m_root(root)
198     , m_current(current)
199 #if !ASSERT_DISABLED
200     , m_assertions(current)
201 #endif
202 {
203 }
204
205 template <typename ElementType>
206 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseNext()
207 {
208     ASSERT(m_current);
209     ASSERT(!m_assertions.domTreeHasMutated());
210     m_current = Traversal<ElementType>::next(m_current, m_root);
211 #if !ASSERT_DISABLED
212     // Drop the assertion when the iterator reaches the end.
213     if (!m_current)
214         m_assertions.dropEventDispatchAssertion();
215 #endif
216     return *this;
217 }
218
219 template <typename ElementType>
220 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traversePrevious()
221 {
222     ASSERT(m_current);
223     ASSERT(!m_assertions.domTreeHasMutated());
224     m_current = Traversal<ElementType>::previous(m_current, m_root);
225 #if !ASSERT_DISABLED
226     // Drop the assertion when the iterator reaches the end.
227     if (!m_current)
228         m_assertions.dropEventDispatchAssertion();
229 #endif
230     return *this;
231 }
232
233 template <typename ElementType>
234 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseNextSibling()
235 {
236     ASSERT(m_current);
237     ASSERT(!m_assertions.domTreeHasMutated());
238     m_current = Traversal<ElementType>::nextSibling(m_current);
239 #if !ASSERT_DISABLED
240     // Drop the assertion when the iterator reaches the end.
241     if (!m_current)
242         m_assertions.dropEventDispatchAssertion();
243 #endif
244     return *this;
245 }
246
247 template <typename ElementType>
248 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traversePreviousSibling()
249 {
250     ASSERT(m_current);
251     ASSERT(!m_assertions.domTreeHasMutated());
252     m_current = Traversal<ElementType>::previousSibling(m_current);
253 #if !ASSERT_DISABLED
254     // Drop the assertion when the iterator reaches the end.
255     if (!m_current)
256         m_assertions.dropEventDispatchAssertion();
257 #endif
258     return *this;
259 }
260
261 template <typename ElementType>
262 inline const ElementType& ElementConstIterator<ElementType>::operator*() const
263 {
264     ASSERT(m_current);
265     ASSERT(!m_assertions.domTreeHasMutated());
266     return *m_current;
267 }
268
269 template <typename ElementType>
270 inline const ElementType* ElementConstIterator<ElementType>::operator->() const
271 {
272     ASSERT(m_current);
273     ASSERT(!m_assertions.domTreeHasMutated());
274     return m_current;
275 }
276
277 template <typename ElementType>
278 inline bool ElementConstIterator<ElementType>::operator!=(const ElementConstIterator& other) const
279 {
280     ASSERT(m_root == other.m_root);
281     ASSERT(!m_assertions.domTreeHasMutated());
282     return m_current != other.m_current;
283 }
284
285 }
286
287 #include "ElementChildIterator.h"
288 #include "ElementDescendantIterator.h"
289
290 #endif