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 "ElementIterator.h"
29
30namespace WebCore {
31
32template <typename ElementType>
33class ElementChildIterator : public ElementIterator<ElementType> {
34public:
35 typedef ElementType value_type;
36 typedef ptrdiff_t difference_type;
37 typedef ElementType* pointer;
38 typedef ElementType& reference;
39 typedef std::forward_iterator_tag iterator_category;
40
41 ElementChildIterator(const ContainerNode& parent);
42 ElementChildIterator(const ContainerNode& parent, ElementType* current);
43 ElementChildIterator& operator--();
44 ElementChildIterator& operator++();
45};
46
47template <typename ElementType>
48class ElementChildConstIterator : public ElementConstIterator<ElementType> {
49public:
50 typedef const ElementType value_type;
51 typedef ptrdiff_t difference_type;
52 typedef const ElementType* pointer;
53 typedef const ElementType& reference;
54 typedef std::forward_iterator_tag iterator_category;
55
56 ElementChildConstIterator(const ContainerNode& parent);
57 ElementChildConstIterator(const ContainerNode& parent, const ElementType* current);
58 ElementChildConstIterator& operator--();
59 ElementChildConstIterator& operator++();
60};
61
62template <typename ElementType>
63class ElementChildIteratorAdapter {
64public:
65 ElementChildIteratorAdapter(ContainerNode& parent);
66
67 ElementChildIterator<ElementType> begin();
68 ElementChildIterator<ElementType> end();
69 ElementChildIterator<ElementType> beginAt(ElementType&);
70
71 ElementType* first();
72 ElementType* last();
73
74private:
75 ContainerNode& m_parent;
76};
77
78template <typename ElementType>
79class ElementChildConstIteratorAdapter {
80public:
81 ElementChildConstIteratorAdapter(const ContainerNode& parent);
82
83 ElementChildConstIterator<ElementType> begin() const;
84 ElementChildConstIterator<ElementType> end() const;
85 ElementChildConstIterator<ElementType> beginAt(const ElementType&) const;
86
87 const ElementType* first() const;
88 const ElementType* last() const;
89
90private:
91 const ContainerNode& m_parent;
92};
93
94template <typename ElementType> ElementChildIteratorAdapter<ElementType> childrenOfType(ContainerNode&);
95template <typename ElementType> ElementChildConstIteratorAdapter<ElementType> childrenOfType(const ContainerNode&);
96
97// ElementChildIterator
98
99template <typename ElementType>
100inline ElementChildIterator<ElementType>::ElementChildIterator(const ContainerNode& parent)
101 : ElementIterator<ElementType>(&parent)
102{
103}
104
105template <typename ElementType>
106inline ElementChildIterator<ElementType>::ElementChildIterator(const ContainerNode& parent, ElementType* current)
107 : ElementIterator<ElementType>(&parent, current)
108{
109}
110
111template <typename ElementType>
112inline ElementChildIterator<ElementType>& ElementChildIterator<ElementType>::operator--()
113{
114 return static_cast<ElementChildIterator<ElementType>&>(ElementIterator<ElementType>::traversePreviousSibling());
115}
116
117template <typename ElementType>
118inline ElementChildIterator<ElementType>& ElementChildIterator<ElementType>::operator++()
119{
120 return static_cast<ElementChildIterator<ElementType>&>(ElementIterator<ElementType>::traverseNextSibling());
121}
122
123// ElementChildConstIterator
124
125template <typename ElementType>
126inline ElementChildConstIterator<ElementType>::ElementChildConstIterator(const ContainerNode& parent)
127 : ElementConstIterator<ElementType>(&parent)
128{
129}
130
131template <typename ElementType>
132inline ElementChildConstIterator<ElementType>::ElementChildConstIterator(const ContainerNode& parent, const ElementType* current)
133 : ElementConstIterator<ElementType>(&parent, current)
134{
135}
136
137template <typename ElementType>
138inline ElementChildConstIterator<ElementType>& ElementChildConstIterator<ElementType>::operator--()
139{
140 return static_cast<ElementChildConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traversePreviousSibling());
141}
142
143
144template <typename ElementType>
145inline ElementChildConstIterator<ElementType>& ElementChildConstIterator<ElementType>::operator++()
146{
147 return static_cast<ElementChildConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseNextSibling());
148}
149
150// ElementChildIteratorAdapter
151
152template <typename ElementType>
153inline ElementChildIteratorAdapter<ElementType>::ElementChildIteratorAdapter(ContainerNode& parent)
154 : m_parent(parent)
155{
156}
157
158template <typename ElementType>
159inline ElementChildIterator<ElementType> ElementChildIteratorAdapter<ElementType>::begin()
160{
161 return ElementChildIterator<ElementType>(m_parent, Traversal<ElementType>::firstChild(m_parent));
162}
163
164template <typename ElementType>
165inline ElementChildIterator<ElementType> ElementChildIteratorAdapter<ElementType>::end()
166{
167 return ElementChildIterator<ElementType>(m_parent);
168}
169
170template <typename ElementType>
171inline ElementType* ElementChildIteratorAdapter<ElementType>::first()
172{
173 return Traversal<ElementType>::firstChild(m_parent);
174}
175
176template <typename ElementType>
177inline ElementType* ElementChildIteratorAdapter<ElementType>::last()
178{
179 return Traversal<ElementType>::lastChild(m_parent);
180}
181
182template <typename ElementType>
183inline ElementChildIterator<ElementType> ElementChildIteratorAdapter<ElementType>::beginAt(ElementType& child)
184{
185 ASSERT(child.parentNode() == &m_parent);
186 return ElementChildIterator<ElementType>(m_parent, &child);
187}
188
189// ElementChildConstIteratorAdapter
190
191template <typename ElementType>
192inline ElementChildConstIteratorAdapter<ElementType>::ElementChildConstIteratorAdapter(const ContainerNode& parent)
193 : m_parent(parent)
194{
195}
196
197template <typename ElementType>
198inline ElementChildConstIterator<ElementType> ElementChildConstIteratorAdapter<ElementType>::begin() const
199{
200 return ElementChildConstIterator<ElementType>(m_parent, Traversal<ElementType>::firstChild(m_parent));
201}
202
203template <typename ElementType>
204inline ElementChildConstIterator<ElementType> ElementChildConstIteratorAdapter<ElementType>::end() const
205{
206 return ElementChildConstIterator<ElementType>(m_parent);
207}
208
209template <typename ElementType>
210inline const ElementType* ElementChildConstIteratorAdapter<ElementType>::first() const
211{
212 return Traversal<ElementType>::firstChild(m_parent);
213}
214
215template <typename ElementType>
216inline const ElementType* ElementChildConstIteratorAdapter<ElementType>::last() const
217{
218 return Traversal<ElementType>::lastChild(m_parent);
219}
220
221template <typename ElementType>
222inline ElementChildConstIterator<ElementType> ElementChildConstIteratorAdapter<ElementType>::beginAt(const ElementType& child) const
223{
224 ASSERT(child.parentNode() == &m_parent);
225 return ElementChildConstIterator<ElementType>(m_parent, &child);
226}
227
228// Standalone functions
229
230template <typename ElementType>
231inline ElementChildIteratorAdapter<ElementType> childrenOfType(ContainerNode& parent)
232{
233 return ElementChildIteratorAdapter<ElementType>(parent);
234}
235
236template <typename ElementType>
237inline ElementChildConstIteratorAdapter<ElementType> childrenOfType(const ContainerNode& parent)
238{
239 return ElementChildConstIteratorAdapter<ElementType>(parent);
240}
241
242} // namespace WebCore
243