Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / dom / TypedElementDescendantIterator.h
1 /*
2  * Copyright (C) 2013-2015 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 TypedElementDescendantIterator_h
27 #define TypedElementDescendantIterator_h
28
29 #include "ElementIterator.h"
30
31 namespace WebCore {
32
33 template<typename ElementType> class DoubleTypedElementDescendantIterator;
34
35 template <typename ElementType>
36 class TypedElementDescendantIterator : public ElementIterator<ElementType> {
37 public:
38     TypedElementDescendantIterator(const ContainerNode& root);
39     TypedElementDescendantIterator(const ContainerNode& root, ElementType* current);
40     TypedElementDescendantIterator& operator++();
41 };
42
43 template <typename ElementType>
44 class TypedElementDescendantConstIterator : public ElementConstIterator<ElementType>  {
45 public:
46     TypedElementDescendantConstIterator(const ContainerNode& root);
47     TypedElementDescendantConstIterator(const ContainerNode& root, const ElementType* current);
48     TypedElementDescendantConstIterator& operator++();
49 };
50
51 template <typename ElementType>
52 class TypedElementDescendantIteratorAdapter {
53 public:
54     TypedElementDescendantIteratorAdapter(ContainerNode& root);
55     TypedElementDescendantIterator<ElementType> begin();
56     TypedElementDescendantIterator<ElementType> end();
57     TypedElementDescendantIterator<ElementType> beginAt(ElementType&);
58     TypedElementDescendantIterator<ElementType> from(Element&);
59
60     ElementType* first();
61     ElementType* last();
62
63 private:
64     ContainerNode& m_root;
65 };
66
67 template <typename ElementType>
68 class TypedElementDescendantConstIteratorAdapter {
69 public:
70     TypedElementDescendantConstIteratorAdapter(const ContainerNode& root);
71     TypedElementDescendantConstIterator<ElementType> begin() const;
72     TypedElementDescendantConstIterator<ElementType> end() const;
73     TypedElementDescendantConstIterator<ElementType> beginAt(const ElementType&) const;
74     TypedElementDescendantConstIterator<ElementType> from(const Element&) const;
75
76     const ElementType* first() const;
77     const ElementType* last() const;
78
79 private:
80     const ContainerNode& m_root;
81 };
82
83 template<typename ElementType> class DoubleTypedElementDescendantIteratorAdapter {
84 public:
85     typedef TypedElementDescendantIteratorAdapter<ElementType> SingleAdapter;
86     typedef DoubleTypedElementDescendantIterator<ElementType> Iterator;
87
88     DoubleTypedElementDescendantIteratorAdapter(SingleAdapter&&, SingleAdapter&&);
89     Iterator begin();
90     Iterator end();
91
92 private:
93     std::pair<SingleAdapter, SingleAdapter> m_pair;
94 };
95
96 template<typename ElementType> class DoubleTypedElementDescendantIterator {
97 public:
98     typedef TypedElementDescendantIterator<ElementType> SingleIterator;
99     typedef std::pair<ElementType&, ElementType&> ReferenceProxy;
100
101     DoubleTypedElementDescendantIterator(SingleIterator&&, SingleIterator&&);
102     ReferenceProxy operator*() const;
103     bool operator==(const DoubleTypedElementDescendantIterator&) const;
104     bool operator!=(const DoubleTypedElementDescendantIterator&) const;
105     DoubleTypedElementDescendantIterator& operator++();
106
107 private:
108     std::pair<SingleIterator, SingleIterator> m_pair;
109 };
110
111 template <typename ElementType> TypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode&);
112 template <typename ElementType> TypedElementDescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode&);
113
114 // This must only be used when both sets of descendants are known to be the same length.
115 // If they are different lengths, this will stop when the shorter one reaches the end, but also an assertion will fail.
116 template<typename ElementType> DoubleTypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& firstRoot, ContainerNode& secondRoot);
117
118 // TypedElementDescendantIterator
119
120 template <typename ElementType>
121 inline TypedElementDescendantIterator<ElementType>::TypedElementDescendantIterator(const ContainerNode& root)
122     : ElementIterator<ElementType>(&root)
123 {
124 }
125
126 template <typename ElementType>
127 inline TypedElementDescendantIterator<ElementType>::TypedElementDescendantIterator(const ContainerNode& root, ElementType* current)
128     : ElementIterator<ElementType>(&root, current)
129 {
130 }
131
132 template <typename ElementType>
133 inline TypedElementDescendantIterator<ElementType>& TypedElementDescendantIterator<ElementType>::operator++()
134 {
135     return static_cast<TypedElementDescendantIterator<ElementType>&>(ElementIterator<ElementType>::traverseNext());
136 }
137
138 // TypedElementDescendantConstIterator
139
140 template <typename ElementType>
141 inline TypedElementDescendantConstIterator<ElementType>::TypedElementDescendantConstIterator(const ContainerNode& root)
142     : ElementConstIterator<ElementType>(&root)
143
144 {
145 }
146
147 template <typename ElementType>
148 inline TypedElementDescendantConstIterator<ElementType>::TypedElementDescendantConstIterator(const ContainerNode& root, const ElementType* current)
149     : ElementConstIterator<ElementType>(&root, current)
150 {
151 }
152
153 template <typename ElementType>
154 inline TypedElementDescendantConstIterator<ElementType>& TypedElementDescendantConstIterator<ElementType>::operator++()
155 {
156     return static_cast<TypedElementDescendantConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseNext());
157 }
158
159 // TypedElementDescendantIteratorAdapter
160
161 template <typename ElementType>
162 inline TypedElementDescendantIteratorAdapter<ElementType>::TypedElementDescendantIteratorAdapter(ContainerNode& root)
163     : m_root(root)
164 {
165 }
166
167 template <typename ElementType>
168 inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::begin()
169 {
170     return TypedElementDescendantIterator<ElementType>(m_root, Traversal<ElementType>::firstWithin(m_root));
171 }
172
173 template <typename ElementType>
174 inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::end()
175 {
176     return TypedElementDescendantIterator<ElementType>(m_root);
177 }
178     
179 template <typename ElementType>
180 inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::beginAt(ElementType& descendant)
181 {
182     ASSERT(descendant.isDescendantOf(&m_root));
183     return TypedElementDescendantIterator<ElementType>(m_root, &descendant);
184 }
185
186 template <typename ElementType>
187 inline TypedElementDescendantIterator<ElementType> TypedElementDescendantIteratorAdapter<ElementType>::from(Element& descendant)
188 {
189     ASSERT(descendant.isDescendantOf(&m_root));
190     if (is<ElementType>(descendant))
191         return TypedElementDescendantIterator<ElementType>(m_root, downcast<ElementType>(&descendant));
192     ElementType* next = Traversal<ElementType>::next(descendant, &m_root);
193     return TypedElementDescendantIterator<ElementType>(m_root, next);
194 }
195
196 template <typename ElementType>
197 inline ElementType* TypedElementDescendantIteratorAdapter<ElementType>::first()
198 {
199     return Traversal<ElementType>::firstWithin(m_root);
200 }
201
202 template <typename ElementType>
203 inline ElementType* TypedElementDescendantIteratorAdapter<ElementType>::last()
204 {
205     return Traversal<ElementType>::lastWithin(m_root);
206 }
207
208 // TypedElementDescendantConstIteratorAdapter
209
210 template <typename ElementType>
211 inline TypedElementDescendantConstIteratorAdapter<ElementType>::TypedElementDescendantConstIteratorAdapter(const ContainerNode& root)
212     : m_root(root)
213 {
214 }
215
216 template <typename ElementType>
217 inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::begin() const
218 {
219     return TypedElementDescendantConstIterator<ElementType>(m_root, Traversal<ElementType>::firstWithin(m_root));
220 }
221
222 template <typename ElementType>
223 inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::end() const
224 {
225     return TypedElementDescendantConstIterator<ElementType>(m_root);
226 }
227
228 template <typename ElementType>
229 inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::beginAt(const ElementType& descendant) const
230 {
231     ASSERT(descendant.isDescendantOf(&m_root));
232     return TypedElementDescendantConstIterator<ElementType>(m_root, &descendant);
233 }
234
235 template <typename ElementType>
236 inline TypedElementDescendantConstIterator<ElementType> TypedElementDescendantConstIteratorAdapter<ElementType>::from(const Element& descendant) const
237 {
238     ASSERT(descendant.isDescendantOf(&m_root));
239     if (is<ElementType>(descendant))
240         return TypedElementDescendantConstIterator<ElementType>(m_root, downcast<ElementType>(&descendant));
241     const ElementType* next = Traversal<ElementType>::next(descendant, &m_root);
242     return TypedElementDescendantConstIterator<ElementType>(m_root, next);
243 }
244
245 template <typename ElementType>
246 inline const ElementType* TypedElementDescendantConstIteratorAdapter<ElementType>::first() const
247 {
248     return Traversal<ElementType>::firstWithin(m_root);
249 }
250
251 template <typename ElementType>
252 inline const ElementType* TypedElementDescendantConstIteratorAdapter<ElementType>::last() const
253 {
254     return Traversal<ElementType>::lastWithin(m_root);
255 }
256
257 // DoubleTypedElementDescendantIteratorAdapter
258
259 template<typename ElementType> inline DoubleTypedElementDescendantIteratorAdapter<ElementType>::DoubleTypedElementDescendantIteratorAdapter(SingleAdapter&& first, SingleAdapter&& second)
260     : m_pair(WTFMove(first), WTFMove(second))
261 {
262 }
263
264 template<typename ElementType> inline auto DoubleTypedElementDescendantIteratorAdapter<ElementType>::begin() -> Iterator
265 {
266     return Iterator(m_pair.first.begin(), m_pair.second.begin());
267 }
268
269 template<typename ElementType> inline auto DoubleTypedElementDescendantIteratorAdapter<ElementType>::end() -> Iterator
270 {
271     return Iterator(m_pair.first.end(), m_pair.second.end());
272 }
273
274 // DoubleTypedElementDescendantIterator
275
276 template<typename ElementType> inline DoubleTypedElementDescendantIterator<ElementType>::DoubleTypedElementDescendantIterator(SingleIterator&& first, SingleIterator&& second)
277     : m_pair(WTFMove(first), WTFMove(second))
278 {
279 }
280
281 template<typename ElementType> inline auto DoubleTypedElementDescendantIterator<ElementType>::operator*() const -> ReferenceProxy
282 {
283     return { *m_pair.first, *m_pair.second };
284 }
285
286 template<typename ElementType> inline bool DoubleTypedElementDescendantIterator<ElementType>::operator==(const DoubleTypedElementDescendantIterator& other) const
287 {
288     ASSERT((m_pair.first == other.m_pair.first) == (m_pair.second == other.m_pair.second));
289     return m_pair.first == other.m_pair.first || m_pair.second == other.m_pair.second;
290 }
291
292 template<typename ElementType> inline bool DoubleTypedElementDescendantIterator<ElementType>::operator!=(const DoubleTypedElementDescendantIterator& other) const
293 {
294     return !(*this == other);
295 }
296
297 template<typename ElementType> inline DoubleTypedElementDescendantIterator<ElementType>& DoubleTypedElementDescendantIterator<ElementType>::operator++()
298 {
299     ++m_pair.first;
300     ++m_pair.second;
301     return *this;
302 }
303
304 // Standalone functions
305
306 template <typename ElementType>
307 inline TypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& root)
308 {
309     return TypedElementDescendantIteratorAdapter<ElementType>(root);
310 }
311
312 template <typename ElementType>
313 inline TypedElementDescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode& root)
314 {
315     return TypedElementDescendantConstIteratorAdapter<ElementType>(root);
316 }
317
318 template<typename ElementType> inline DoubleTypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& firstRoot, ContainerNode& secondRoot)
319 {
320     return { descendantsOfType<ElementType>(firstRoot), descendantsOfType<ElementType>(secondRoot) };
321 }
322
323 }
324
325 #endif