OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // FIXME: lifetime management could be parameterized so that ref counted impl
ementations can be used. | 43 // FIXME: lifetime management could be parameterized so that ref counted impl
ementations can be used. |
44 // * It ASSERT()s invalid input. The callers have to ensure that given paramete
r is sound. | 44 // * It ASSERT()s invalid input. The callers have to ensure that given paramete
r is sound. |
45 // * There is no branch-leaf difference. Every node can be a parent of other no
de. | 45 // * There is no branch-leaf difference. Every node can be a parent of other no
de. |
46 // | 46 // |
47 template <class T> | 47 template <class T> |
48 class TreeNode { | 48 class TreeNode { |
49 public: | 49 public: |
50 typedef T NodeType; | 50 typedef T NodeType; |
51 | 51 |
52 TreeNode() | 52 TreeNode() |
53 : m_nextSibling(0) | 53 : m_next(0) |
54 , m_previousSibling(0) | 54 , m_previous(0) |
55 , m_parent(0) | 55 , m_parent(0) |
56 , m_firstChild(0) | 56 , m_firstChild(0) |
57 , m_lastChild(0) | 57 , m_lastChild(0) |
58 { | 58 { |
59 } | 59 } |
60 | 60 |
61 NodeType* nextSibling() const { return m_nextSibling; } | 61 NodeType* next() const { return m_next; } |
62 NodeType* previousSibling() const { return m_previousSibling; } | 62 NodeType* previous() const { return m_previous; } |
63 NodeType* parent() const { return m_parent; } | 63 NodeType* parent() const { return m_parent; } |
64 NodeType* firstChild() const { return m_firstChild; } | 64 NodeType* firstChild() const { return m_firstChild; } |
65 NodeType* lastChild() const { return m_lastChild; } | 65 NodeType* lastChild() const { return m_lastChild; } |
66 NodeType* here() const { return static_cast<NodeType*>(const_cast<TreeNode*>
(this)); } | 66 NodeType* here() const { return static_cast<NodeType*>(const_cast<TreeNode*>
(this)); } |
67 | 67 |
68 bool orphan() const { return !m_parent && !m_nextSibling && !m_previousSibli
ng && !m_firstChild && !m_lastChild; } | 68 bool orphan() const { return !m_parent && !m_next && !m_previous && !m_first
Child && !m_lastChild; } |
69 bool hasChildren() const { return m_firstChild; } | 69 bool hasChildren() const { return m_firstChild; } |
70 | 70 |
71 void insertBefore(NodeType* newChild, NodeType* refChild) | 71 void insertBefore(NodeType* newChild, NodeType* refChild) |
72 { | 72 { |
73 ASSERT(!newChild->parent()); | 73 ASSERT(!newChild->parent()); |
74 ASSERT(!newChild->nextSibling()); | 74 ASSERT(!newChild->next()); |
75 ASSERT(!newChild->previousSibling()); | 75 ASSERT(!newChild->previous()); |
76 | 76 |
77 ASSERT(!refChild || this == refChild->parent()); | 77 ASSERT(!refChild || this == refChild->parent()); |
78 | 78 |
79 if (!refChild) { | 79 if (!refChild) { |
80 appendChild(newChild); | 80 appendChild(newChild); |
81 return; | 81 return; |
82 } | 82 } |
83 | 83 |
84 NodeType* newPrevious = refChild->previousSibling(); | 84 NodeType* newPrevious = refChild->previous(); |
85 newChild->m_parent = here(); | 85 newChild->m_parent = here(); |
86 newChild->m_nextSibling = refChild; | 86 newChild->m_next = refChild; |
87 newChild->m_previousSibling = newPrevious; | 87 newChild->m_previous = newPrevious; |
88 refChild->m_previousSibling = newChild; | 88 refChild->m_previous = newChild; |
89 if (newPrevious) | 89 if (newPrevious) |
90 newPrevious->m_nextSibling = newChild; | 90 newPrevious->m_next = newChild; |
91 else | 91 else |
92 m_firstChild = newChild; | 92 m_firstChild = newChild; |
93 } | 93 } |
94 | 94 |
95 void appendChild(NodeType* child) | 95 void appendChild(NodeType* child) |
96 { | 96 { |
97 ASSERT(!child->parent()); | 97 ASSERT(!child->parent()); |
98 ASSERT(!child->nextSibling()); | 98 ASSERT(!child->next()); |
99 ASSERT(!child->previousSibling()); | 99 ASSERT(!child->previous()); |
100 | 100 |
101 child->m_parent = here(); | 101 child->m_parent = here(); |
102 | 102 |
103 if (!m_lastChild) { | 103 if (!m_lastChild) { |
104 ASSERT(!m_firstChild); | 104 ASSERT(!m_firstChild); |
105 m_lastChild = m_firstChild = child; | 105 m_lastChild = m_firstChild = child; |
106 return; | 106 return; |
107 } | 107 } |
108 | 108 |
109 ASSERT(!m_lastChild->m_nextSibling); | 109 ASSERT(!m_lastChild->m_next); |
110 NodeType* oldLast = m_lastChild; | 110 NodeType* oldLast = m_lastChild; |
111 m_lastChild = child; | 111 m_lastChild = child; |
112 | 112 |
113 child->m_previousSibling = oldLast; | 113 child->m_previous = oldLast; |
114 oldLast->m_nextSibling = child; | 114 oldLast->m_next = child; |
115 } | 115 } |
116 | 116 |
117 NodeType* removeChild(NodeType* child) | 117 NodeType* removeChild(NodeType* child) |
118 { | 118 { |
119 ASSERT(child->parent() == this); | 119 ASSERT(child->parent() == this); |
120 | 120 |
121 if (m_firstChild == child) | 121 if (m_firstChild == child) |
122 m_firstChild = child->nextSibling(); | 122 m_firstChild = child->next(); |
123 if (m_lastChild == child) | 123 if (m_lastChild == child) |
124 m_lastChild = child->previousSibling(); | 124 m_lastChild = child->previous(); |
125 | 125 |
126 NodeType* oldNext = child->nextSibling(); | 126 NodeType* oldNext = child->next(); |
127 NodeType* oldPrevious = child->previousSibling(); | 127 NodeType* oldPrevious = child->previous(); |
128 child->m_parent = child->m_nextSibling = child->m_previousSibling = 0; | 128 child->m_parent = child->m_next = child->m_previous = 0; |
129 | 129 |
130 if (oldNext) | 130 if (oldNext) |
131 oldNext->m_previousSibling = oldPrevious; | 131 oldNext->m_previous = oldPrevious; |
132 if (oldPrevious) | 132 if (oldPrevious) |
133 oldPrevious->m_nextSibling = oldNext; | 133 oldPrevious->m_next = oldNext; |
134 | 134 |
135 return child; | 135 return child; |
136 } | 136 } |
137 | 137 |
138 private: | 138 private: |
139 NodeType* m_nextSibling; | 139 NodeType* m_next; |
140 NodeType* m_previousSibling; | 140 NodeType* m_previous; |
141 NodeType* m_parent; | 141 NodeType* m_parent; |
142 NodeType* m_firstChild; | 142 NodeType* m_firstChild; |
143 NodeType* m_lastChild; | 143 NodeType* m_lastChild; |
144 }; | 144 }; |
145 | 145 |
146 /* non-recursive pre-order traversal */ | 146 template<class T> |
147 template<class NodeType, class ContainerType> | 147 inline typename TreeNode<T>::NodeType* traverseNext(const TreeNode<T>* current,
const TreeNode<T>* stayWithin = 0) |
148 inline NodeType* traverseNext(const ContainerType& current) | |
149 { | 148 { |
150 if (NodeType* firstChild = current.firstChild()) | 149 if (typename TreeNode<T>::NodeType* next = current->firstChild()) |
151 return firstChild; | 150 return next; |
152 if (NodeType* nextSibling = current.nextSibling()) | 151 if (current == stayWithin) |
153 return nextSibling; | 152 return 0; |
154 for (NodeType* parent = current.parent(); parent; parent = parent->parent())
{ | 153 if (typename TreeNode<T>::NodeType* next = current->next()) |
155 if (NodeType* nextSibling = parent->nextSibling()) | 154 return next; |
156 return nextSibling; | 155 for (typename TreeNode<T>::NodeType* parent = current->parent(); parent; par
ent = parent->parent()) { |
| 156 if (parent == stayWithin) |
| 157 return 0; |
| 158 if (typename TreeNode<T>::NodeType* next = parent->next()) |
| 159 return next; |
157 } | 160 } |
158 | 161 |
159 return 0; | 162 return 0; |
160 } | 163 } |
161 | 164 |
162 template<class NodeType, class ContainerType> | 165 template<class T> |
163 inline NodeType* traverseNext(const ContainerType& current, const NodeType* stay
Within) | 166 inline typename TreeNode<T>::NodeType* traverseFirstPostOrder(const TreeNode<T>*
current) |
164 { | 167 { |
165 if (NodeType* firstChild = current.firstChild()) | 168 typename TreeNode<T>::NodeType* first = current->here(); |
166 return firstChild; | |
167 if (¤t == stayWithin) | |
168 return 0; | |
169 if (NodeType* nextSibling = current.nextSibling()) | |
170 return nextSibling; | |
171 for (NodeType* parent = current.parent(); parent; parent = parent->parent())
{ | |
172 if (parent == stayWithin) | |
173 return 0; | |
174 if (NodeType* nextSibling = parent->nextSibling()) | |
175 return nextSibling; | |
176 } | |
177 | |
178 return 0; | |
179 } | |
180 | |
181 /* non-recursive post-order traversal */ | |
182 template<class NodeType, class ContainerType> | |
183 inline NodeType* traverseFirstPostOrder(const ContainerType& current) | |
184 { | |
185 NodeType* first = current.here(); | |
186 while (first->firstChild()) | 169 while (first->firstChild()) |
187 first = first->firstChild(); | 170 first = first->firstChild(); |
188 return first; | 171 return first; |
189 } | 172 } |
190 | 173 |
191 template<class NodeType, class ContainerType> | 174 template<class T> |
192 inline NodeType* traverseNextPostOrder(const ContainerType& current) | 175 inline typename TreeNode<T>::NodeType* traverseNextPostOrder(const TreeNode<T>*
current, const TreeNode<T>* stayWithin = 0) |
193 { | |
194 NodeType* nextSibling = current.nextSibling(); | |
195 if (!nextSibling) | |
196 return current.parent(); | |
197 while (nextSibling->firstChild()) | |
198 nextSibling = nextSibling->firstChild(); | |
199 return nextSibling; | |
200 } | |
201 | |
202 template<class NodeType, class ContainerType> | |
203 inline NodeType* traverseNextPostOrder(const ContainerType& current, const NodeT
ype* stayWithin) | |
204 { | |
205 if (¤t == stayWithin) | |
206 return 0; | |
207 | |
208 NodeType* nextSibling = current.nextSibling(); | |
209 if (!nextSibling) | |
210 return current.parent(); | |
211 while (nextSibling->firstChild()) | |
212 nextSibling = nextSibling->firstChild(); | |
213 return nextSibling; | |
214 } | |
215 | |
216 /* non-recursive traversal skipping children */ | |
217 template <class NodeType, class ContainerType> | |
218 inline NodeType* traverseNextSkippingChildren(const ContainerType& current) | |
219 { | |
220 if (current.nextSibling()) | |
221 return current.nextSibling(); | |
222 for (NodeType* parent = current.parent(); parent; parent = parent->parent())
{ | |
223 if (NodeType* nextSibling = parent->nextSibling()) | |
224 return nextSibling; | |
225 } | |
226 | |
227 return 0; | |
228 } | |
229 | |
230 template <class NodeType, class ContainerType> | |
231 inline NodeType* traverseNextSkippingChildren(const ContainerType& current, cons
t NodeType* stayWithin) | |
232 { | 176 { |
233 if (current == stayWithin) | 177 if (current == stayWithin) |
234 return 0; | 178 return 0; |
235 if (current.nextSibling()) | |
236 return current.nextSibling(); | |
237 for (NodeType* parent = current.parent(); parent; parent = parent->parent())
{ | |
238 if (parent == stayWithin) | |
239 return 0; | |
240 if (NodeType* nextSibling = parent->nextSibling()) | |
241 return nextSibling; | |
242 } | |
243 | 179 |
244 return 0; | 180 typename TreeNode<T>::NodeType* next = current->next(); |
| 181 if (!next) |
| 182 return current->parent(); |
| 183 while (next->firstChild()) |
| 184 next = next->firstChild(); |
| 185 return next; |
245 } | 186 } |
246 | 187 |
247 } // namespace WTF | 188 } |
248 | 189 |
249 using WTF::TreeNode; | 190 using WTF::TreeNode; |
250 using WTF::traverseNext; | 191 using WTF::traverseNext; |
251 using WTF::traverseFirstPostOrder; | |
252 using WTF::traverseNextPostOrder; | 192 using WTF::traverseNextPostOrder; |
253 using WTF::traverseNextSkippingChildren; | |
254 | 193 |
255 #endif // TreeNode_h | 194 #endif |
OLD | NEW |