00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00037 template<class T> class pgTree
00038 {
00039 public:
00040 pgDefineException(ExceptionInvalidArgument);
00041 pgDefineException(ExceptionInvalidCall);
00042 pgDefineException(ExceptionNotInitialized);
00043
00047 pgTree()
00048 {
00049 m_self = NULL;
00050 m_parent = NULL;
00051 m_last_child = NULL;
00052 m_prev = m_next = NULL;
00053 }
00054
00058 ~pgTree()
00059 {
00060 leave();
00061 clear();
00062 }
00063
00069 void init(T* self)
00070 {
00071 if (!self)
00072 {
00073 pgThrow(ExceptionInvalidArgument);
00074 }
00075
00076 m_self = self;
00077 }
00078
00083 T* getSelf() const
00084 {
00085 if (!m_self)
00086 {
00087 pgThrow(ExceptionNotInitialized);
00088 }
00089
00090 return m_self;
00091 }
00092
00097 bool hasParent() const
00098 {
00099 return m_parent ? true : false;
00100 }
00101
00107 pgTree<T>* getParentN() const
00108 {
00109 return m_parent;
00110 }
00111
00118 pgTree<T>* getPrevAllN() const
00119 {
00120 return m_prev;
00121 }
00122
00129 pgTree<T>* getNextAllN() const
00130 {
00131 return m_next;
00132 }
00133
00139 pgTree<T>* getPrevSiblingN() const
00140 {
00141 if (!hasParent())
00142 {
00143 pgThrow(ExceptionInvalidCall);
00144 }
00145
00146 if (m_prev != m_parent)
00147 {
00148 pgTree<T>* prev = m_prev;
00149
00150 while (prev->m_parent != m_parent)
00151 {
00152 prev = prev->m_parent;
00153 }
00154
00155 return prev;
00156 }
00157 else
00158 {
00159 return NULL;
00160 }
00161 }
00162
00168 pgTree<T>* getNextSiblingN() const
00169 {
00170 if (!hasParent())
00171 {
00172 pgThrow(ExceptionInvalidCall);
00173 }
00174
00175 pgTree<T>* desc = getLastDesc();
00176 pgTree<T>* next = desc->m_next;
00177
00178 return (next && next->m_parent == m_parent) ? next : NULL;
00179 }
00180
00185 void joinBefore(pgTree<T>* tree)
00186 {
00187 if (!tree || tree == this || !tree->hasParent())
00188 {
00189 pgThrow(ExceptionInvalidArgument);
00190 }
00191
00192 for (pgTree<T>* parent = tree->m_parent; parent; parent = parent->m_parent)
00193 {
00194 if (parent == this)
00195 {
00196 pgThrow(ExceptionInvalidArgument);
00197 }
00198 }
00199
00200 leave();
00201
00202 pgTree<T>* desc = getLastDesc();
00203
00204 m_parent = tree->m_parent;
00205 m_prev = tree->m_prev;
00206 desc->m_next = tree;
00207
00208 m_prev->m_next = this;
00209 desc->m_next->m_prev = desc;
00210 }
00211
00216 void joinAfter(pgTree<T>* tree)
00217 {
00218 if (!tree || tree == this || !tree->hasParent())
00219 {
00220 pgThrow(ExceptionInvalidArgument);
00221 }
00222
00223 for (pgTree<T>* parent = tree->m_parent; parent; parent = parent->m_parent)
00224 {
00225 if (parent == this)
00226 {
00227 pgThrow(ExceptionInvalidArgument);
00228 }
00229 }
00230
00231 leave();
00232
00233 pgTree<T>* tree_desc = tree->getLastDesc();
00234 pgTree<T>* this_desc = getLastDesc();
00235
00236 m_parent = tree->m_parent;
00237 m_prev = tree_desc;
00238 this_desc->m_next = tree_desc->m_next;
00239
00240 m_prev->m_next = this;
00241
00242 if (this_desc->m_next)
00243 {
00244 this_desc->m_next->m_prev = this_desc;
00245 }
00246
00247 if (m_parent->m_last_child == tree)
00248 {
00249 m_parent->m_last_child = this;
00250 }
00251 }
00252
00256 void leave()
00257 {
00258 if (hasParent())
00259 {
00260 pgTree<T>* desc = getLastDesc();
00261
00262 if (m_parent->m_last_child == this)
00263 {
00264 m_parent->m_last_child = getPrevSiblingN();
00265 }
00266
00267 m_prev->m_next = desc->m_next;
00268
00269 if (desc->m_next)
00270 {
00271 desc->m_next->m_prev = m_prev;
00272 }
00273
00274 m_parent = NULL;
00275 m_prev = desc->m_next = NULL;
00276 }
00277 }
00278
00283 bool hasChild() const
00284 {
00285 return m_last_child ? true : false;
00286 }
00287
00293 pgTree<T>* getFirstChildN() const
00294 {
00295 return hasChild() ? m_next : NULL;
00296 }
00297
00303 pgTree<T>* getLastChildN() const
00304 {
00305 return m_last_child;
00306 }
00307
00313 pgTree<T>* getLastDesc() const
00314 {
00315 pgTree<T>* desc = const_cast<pgTree<T>*>(this);
00316
00317 while (desc->m_last_child)
00318 {
00319 desc = desc->m_last_child;
00320 }
00321
00322 return desc;
00323 }
00324
00329 void addFirst(pgTree<T>* child)
00330 {
00331 if (!child || child == this)
00332 {
00333 pgThrow(ExceptionInvalidArgument);
00334 }
00335
00336 for (pgTree<T>* parent = m_parent; parent; parent = parent->m_parent)
00337 {
00338 if (parent == child)
00339 {
00340 pgThrow(ExceptionInvalidArgument);
00341 }
00342 }
00343
00344 child->leave();
00345
00346 pgTree<T>* child_desc = child->getLastDesc();
00347
00348 child->m_parent = this;
00349 child->m_prev = this;
00350 child_desc->m_next = m_next;
00351
00352 child->m_prev->m_next = child;
00353
00354 if (child_desc->m_next)
00355 {
00356 child_desc->m_next->m_prev = child_desc;
00357 }
00358
00359 if (!m_last_child)
00360 {
00361 m_last_child = child;
00362 }
00363 }
00364
00369 void addLast(pgTree<T>* child)
00370 {
00371 if (!child || child == this)
00372 {
00373 pgThrow(ExceptionInvalidArgument);
00374 }
00375
00376 for (pgTree<T>* parent = m_parent; parent; parent = parent->m_parent)
00377 {
00378 if (parent == child)
00379 {
00380 pgThrow(ExceptionInvalidArgument);
00381 }
00382 }
00383
00384 child->leave();
00385
00386 pgTree<T>* this_desc = getLastDesc();
00387 pgTree<T>* child_desc = child->getLastDesc();
00388
00389 child->m_parent = this;
00390 child->m_prev = this_desc;
00391 child_desc->m_next = this_desc->m_next;
00392
00393 child->m_prev->m_next = child;
00394
00395 if (child_desc->m_next)
00396 {
00397 child_desc->m_next->m_prev = child_desc;
00398 }
00399
00400 m_last_child = child;
00401 }
00402
00406 void clear()
00407 {
00408 while (hasChild())
00409 {
00410 getFirstChildN()->leave();
00411 }
00412 }
00413
00414 private:
00415 pgTree(const pgTree<T>&) {}
00416 void operator=(const pgTree<T>&) {}
00417
00418 T* m_self;
00419 pgTree<T>* m_parent;
00420 pgTree<T>* m_last_child;
00421 pgTree<T>* m_prev;
00422 pgTree<T>* m_next;
00423 };