| 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 30 matching lines...) Expand all Loading... |
| 41 // | 41 // |
| 42 // * Each TreeNode node is NOT ref counted. The user have to retain its lifetim
e somehow. | 42 // * Each TreeNode node is NOT ref counted. The user have to retain its lifetim
e somehow. |
| 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 // FIXME: oilpan: Trace tree node edges to ensure we don't have dangling pointer
s. | 47 // FIXME: oilpan: Trace tree node edges to ensure we don't have dangling pointer
s. |
| 48 // As it is used in HTMLImport it is safe since they all die together. | 48 // As it is used in HTMLImport it is safe since they all die together. |
| 49 template <class T> | 49 template <class T> |
| 50 class TreeNode { | 50 class TreeNode { |
| 51 public: | 51 public: |
| 52 typedef T NodeType; | 52 typedef T NodeType; |
| 53 | 53 |
| 54 TreeNode() | 54 TreeNode() |
| 55 : m_next(0) | 55 : m_next(0), m_previous(0), m_parent(0), m_firstChild(0), m_lastChild(0) { |
| 56 , m_previous(0) | 56 } |
| 57 , m_parent(0) | 57 |
| 58 , m_firstChild(0) | 58 NodeType* next() const { return m_next; } |
| 59 , m_lastChild(0) | 59 NodeType* previous() const { return m_previous; } |
| 60 { | 60 NodeType* parent() const { return m_parent; } |
| 61 NodeType* firstChild() const { return m_firstChild; } |
| 62 NodeType* lastChild() const { return m_lastChild; } |
| 63 NodeType* here() const { return static_cast<NodeType*>(const_cast<TreeNode*>(t
his)); } |
| 64 |
| 65 bool orphan() const { return !m_parent && !m_next && !m_previous && !m_firstCh
ild && !m_lastChild; } |
| 66 bool hasChildren() const { return m_firstChild; } |
| 67 |
| 68 void insertBefore(NodeType* newChild, NodeType* refChild) { |
| 69 ASSERT(!newChild->parent()); |
| 70 ASSERT(!newChild->next()); |
| 71 ASSERT(!newChild->previous()); |
| 72 |
| 73 ASSERT(!refChild || this == refChild->parent()); |
| 74 |
| 75 if (!refChild) { |
| 76 appendChild(newChild); |
| 77 return; |
| 61 } | 78 } |
| 62 | 79 |
| 63 NodeType* next() const { return m_next; } | 80 NodeType* newPrevious = refChild->previous(); |
| 64 NodeType* previous() const { return m_previous; } | 81 newChild->m_parent = here(); |
| 65 NodeType* parent() const { return m_parent; } | 82 newChild->m_next = refChild; |
| 66 NodeType* firstChild() const { return m_firstChild; } | 83 newChild->m_previous = newPrevious; |
| 67 NodeType* lastChild() const { return m_lastChild; } | 84 refChild->m_previous = newChild; |
| 68 NodeType* here() const { return static_cast<NodeType*>(const_cast<TreeNode*>
(this)); } | 85 if (newPrevious) |
| 86 newPrevious->m_next = newChild; |
| 87 else |
| 88 m_firstChild = newChild; |
| 89 } |
| 69 | 90 |
| 70 bool orphan() const { return !m_parent && !m_next && !m_previous && !m_first
Child && !m_lastChild; } | 91 void appendChild(NodeType* child) { |
| 71 bool hasChildren() const { return m_firstChild; } | 92 ASSERT(!child->parent()); |
| 93 ASSERT(!child->next()); |
| 94 ASSERT(!child->previous()); |
| 72 | 95 |
| 73 void insertBefore(NodeType* newChild, NodeType* refChild) | 96 child->m_parent = here(); |
| 74 { | |
| 75 ASSERT(!newChild->parent()); | |
| 76 ASSERT(!newChild->next()); | |
| 77 ASSERT(!newChild->previous()); | |
| 78 | 97 |
| 79 ASSERT(!refChild || this == refChild->parent()); | 98 if (!m_lastChild) { |
| 80 | 99 ASSERT(!m_firstChild); |
| 81 if (!refChild) { | 100 m_lastChild = m_firstChild = child; |
| 82 appendChild(newChild); | 101 return; |
| 83 return; | |
| 84 } | |
| 85 | |
| 86 NodeType* newPrevious = refChild->previous(); | |
| 87 newChild->m_parent = here(); | |
| 88 newChild->m_next = refChild; | |
| 89 newChild->m_previous = newPrevious; | |
| 90 refChild->m_previous = newChild; | |
| 91 if (newPrevious) | |
| 92 newPrevious->m_next = newChild; | |
| 93 else | |
| 94 m_firstChild = newChild; | |
| 95 } | 102 } |
| 96 | 103 |
| 97 void appendChild(NodeType* child) | 104 ASSERT(!m_lastChild->m_next); |
| 98 { | 105 NodeType* oldLast = m_lastChild; |
| 99 ASSERT(!child->parent()); | 106 m_lastChild = child; |
| 100 ASSERT(!child->next()); | |
| 101 ASSERT(!child->previous()); | |
| 102 | 107 |
| 103 child->m_parent = here(); | 108 child->m_previous = oldLast; |
| 109 oldLast->m_next = child; |
| 110 } |
| 104 | 111 |
| 105 if (!m_lastChild) { | 112 NodeType* removeChild(NodeType* child) { |
| 106 ASSERT(!m_firstChild); | 113 ASSERT(child->parent() == this); |
| 107 m_lastChild = m_firstChild = child; | |
| 108 return; | |
| 109 } | |
| 110 | 114 |
| 111 ASSERT(!m_lastChild->m_next); | 115 if (m_firstChild == child) |
| 112 NodeType* oldLast = m_lastChild; | 116 m_firstChild = child->next(); |
| 113 m_lastChild = child; | 117 if (m_lastChild == child) |
| 118 m_lastChild = child->previous(); |
| 114 | 119 |
| 115 child->m_previous = oldLast; | 120 NodeType* oldNext = child->next(); |
| 116 oldLast->m_next = child; | 121 NodeType* oldPrevious = child->previous(); |
| 122 child->m_parent = child->m_next = child->m_previous = 0; |
| 123 |
| 124 if (oldNext) |
| 125 oldNext->m_previous = oldPrevious; |
| 126 if (oldPrevious) |
| 127 oldPrevious->m_next = oldNext; |
| 128 |
| 129 return child; |
| 130 } |
| 131 |
| 132 void takeChildrenFrom(NodeType* oldParent) { |
| 133 ASSERT(oldParent != this); |
| 134 while (oldParent->hasChildren()) { |
| 135 NodeType* child = oldParent->firstChild(); |
| 136 oldParent->removeChild(child); |
| 137 this->appendChild(child); |
| 117 } | 138 } |
| 139 } |
| 118 | 140 |
| 119 NodeType* removeChild(NodeType* child) | 141 private: |
| 120 { | 142 NodeType* m_next; |
| 121 ASSERT(child->parent() == this); | 143 NodeType* m_previous; |
| 122 | 144 NodeType* m_parent; |
| 123 if (m_firstChild == child) | 145 NodeType* m_firstChild; |
| 124 m_firstChild = child->next(); | 146 NodeType* m_lastChild; |
| 125 if (m_lastChild == child) | |
| 126 m_lastChild = child->previous(); | |
| 127 | |
| 128 NodeType* oldNext = child->next(); | |
| 129 NodeType* oldPrevious = child->previous(); | |
| 130 child->m_parent = child->m_next = child->m_previous = 0; | |
| 131 | |
| 132 if (oldNext) | |
| 133 oldNext->m_previous = oldPrevious; | |
| 134 if (oldPrevious) | |
| 135 oldPrevious->m_next = oldNext; | |
| 136 | |
| 137 return child; | |
| 138 } | |
| 139 | |
| 140 void takeChildrenFrom(NodeType* oldParent) | |
| 141 { | |
| 142 ASSERT(oldParent != this); | |
| 143 while (oldParent->hasChildren()) { | |
| 144 NodeType* child = oldParent->firstChild(); | |
| 145 oldParent->removeChild(child); | |
| 146 this->appendChild(child); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 private: | |
| 151 NodeType* m_next; | |
| 152 NodeType* m_previous; | |
| 153 NodeType* m_parent; | |
| 154 NodeType* m_firstChild; | |
| 155 NodeType* m_lastChild; | |
| 156 }; | 147 }; |
| 157 | 148 |
| 158 template<class T> | 149 template <class T> |
| 159 inline typename TreeNode<T>::NodeType* traverseNext(const TreeNode<T>* current,
const TreeNode<T>* stayWithin = 0) | 150 inline typename TreeNode<T>::NodeType* traverseNext(const TreeNode<T>* current,
const TreeNode<T>* stayWithin = 0) { |
| 160 { | 151 if (typename TreeNode<T>::NodeType* next = current->firstChild()) |
| 161 if (typename TreeNode<T>::NodeType* next = current->firstChild()) | 152 return next; |
| 162 return next; | 153 if (current == stayWithin) |
| 163 if (current == stayWithin) | 154 return 0; |
| 164 return 0; | 155 if (typename TreeNode<T>::NodeType* next = current->next()) |
| 165 if (typename TreeNode<T>::NodeType* next = current->next()) | 156 return next; |
| 166 return next; | 157 for (typename TreeNode<T>::NodeType* parent = current->parent(); parent; paren
t = parent->parent()) { |
| 167 for (typename TreeNode<T>::NodeType* parent = current->parent(); parent; par
ent = parent->parent()) { | 158 if (parent == stayWithin) |
| 168 if (parent == stayWithin) | 159 return 0; |
| 169 return 0; | 160 if (typename TreeNode<T>::NodeType* next = parent->next()) |
| 170 if (typename TreeNode<T>::NodeType* next = parent->next()) | 161 return next; |
| 171 return next; | 162 } |
| 172 } | |
| 173 | 163 |
| 174 return 0; | 164 return 0; |
| 175 } | 165 } |
| 176 | 166 |
| 177 template<class T> | 167 template <class T> |
| 178 inline typename TreeNode<T>::NodeType* traverseFirstPostOrder(const TreeNode<T>*
current) | 168 inline typename TreeNode<T>::NodeType* traverseFirstPostOrder(const TreeNode<T>*
current) { |
| 179 { | 169 typename TreeNode<T>::NodeType* first = current->here(); |
| 180 typename TreeNode<T>::NodeType* first = current->here(); | 170 while (first->firstChild()) |
| 181 while (first->firstChild()) | 171 first = first->firstChild(); |
| 182 first = first->firstChild(); | 172 return first; |
| 183 return first; | |
| 184 } | 173 } |
| 185 | 174 |
| 186 template<class T> | 175 template <class T> |
| 187 inline typename TreeNode<T>::NodeType* traverseNextPostOrder(const TreeNode<T>*
current, const TreeNode<T>* stayWithin = 0) | 176 inline typename TreeNode<T>::NodeType* traverseNextPostOrder(const TreeNode<T>*
current, const TreeNode<T>* stayWithin = 0) { |
| 188 { | 177 if (current == stayWithin) |
| 189 if (current == stayWithin) | 178 return 0; |
| 190 return 0; | |
| 191 | 179 |
| 192 typename TreeNode<T>::NodeType* next = current->next(); | 180 typename TreeNode<T>::NodeType* next = current->next(); |
| 193 if (!next) | 181 if (!next) |
| 194 return current->parent(); | 182 return current->parent(); |
| 195 while (next->firstChild()) | 183 while (next->firstChild()) |
| 196 next = next->firstChild(); | 184 next = next->firstChild(); |
| 197 return next; | 185 return next; |
| 198 } | 186 } |
| 199 | |
| 200 } | 187 } |
| 201 | 188 |
| 202 using WTF::TreeNode; | 189 using WTF::TreeNode; |
| 203 using WTF::traverseNext; | 190 using WTF::traverseNext; |
| 204 using WTF::traverseNextPostOrder; | 191 using WTF::traverseNextPostOrder; |
| 205 | 192 |
| 206 #endif | 193 #endif |
| OLD | NEW |