00001 //----------------------------------------------------------- 00002 // Copyright Christian Arnault LAL-Orsay CNRS 00003 // arnault@lal.in2p3.fr 00004 // See the complete license in cmt_license.txt "http://www.cecill.info". 00005 //----------------------------------------------------------- 00006 00007 #ifndef __cmt_list_h__ 00008 #define __cmt_list_h__ 00009 00010 #include <iostream> 00011 00012 template <class T> 00013 class cmt_list_node 00014 { 00015 public: 00016 cmt_list_node (const T& t) : m_left(0), m_t(t), m_right(0) 00017 { 00018 } 00019 00020 ~cmt_list_node () 00021 { 00022 } 00023 00024 cmt_list_node<T>* m_left; 00025 T m_t; 00026 cmt_list_node<T>* m_right; 00027 }; 00028 00029 template <class T> 00030 class cmt_list 00031 { 00032 public: 00033 typedef cmt_list_node<T> NodeV; 00034 typedef NodeV* Node; 00035 00036 class iterator 00037 { 00038 public: 00039 iterator () : m_node (0) 00040 { 00041 } 00042 00043 iterator (Node node) : m_node (node) 00044 { 00045 } 00046 00047 iterator& operator ++ () 00048 { 00049 if (m_node == 0) return (*this); 00050 m_node = m_node->m_right; 00051 return (*this); 00052 } 00053 00054 iterator& operator -- () 00055 { 00056 if (m_node == 0) return (*this); 00057 m_node = m_node->m_left; 00058 return (*this); 00059 } 00060 00061 int operator == (const iterator& other) const 00062 { 00063 return (m_node == other.m_node); 00064 } 00065 00066 int operator != (const iterator& other) const 00067 { 00068 const iterator& me = *this; 00069 return (! (me == other)); 00070 } 00071 00072 T& operator * () const 00073 { 00074 if (m_node == 0) 00075 { 00076 static T t; 00077 00078 return (t); 00079 } 00080 else 00081 { 00082 return (m_node->m_t); 00083 } 00084 } 00085 00086 Node get_node () const 00087 { 00088 return (m_node); 00089 } 00090 00091 private: 00092 Node m_node; 00093 }; 00094 00095 class const_iterator 00096 { 00097 public: 00098 const_iterator () : m_node (0) 00099 { 00100 } 00101 00102 const_iterator (const Node node) : m_node (node) 00103 { 00104 } 00105 00106 const_iterator& operator ++ () 00107 { 00108 if (m_node == 0) return (*this); 00109 m_node = m_node->m_right; 00110 return (*this); 00111 } 00112 00113 const_iterator& operator -- () 00114 { 00115 if (m_node == 0) return (*this); 00116 m_node = m_node->m_left; 00117 return (*this); 00118 } 00119 00120 int operator == (const const_iterator& other) const 00121 { 00122 return (m_node == other.m_node); 00123 } 00124 00125 int operator != (const const_iterator& other) const 00126 { 00127 const iterator& me = *this; 00128 return (! (me == other)); 00129 } 00130 00131 const T& operator * () const 00132 { 00133 if (m_node == 0) 00134 { 00135 static const T t; 00136 return (t); 00137 } 00138 else 00139 { 00140 return (m_node->m_t); 00141 } 00142 } 00143 00144 const Node get_node () const 00145 { 00146 return (m_node); 00147 } 00148 00149 private: 00150 const Node m_node; 00151 }; 00152 00153 cmt_list () 00154 { 00155 m_first = 0; 00156 m_last = 0; 00157 } 00158 00159 ~cmt_list () 00160 { 00161 while (m_last != 0) 00162 { 00163 remove (m_last); 00164 } 00165 } 00166 00167 void push_front (const T& t) 00168 { 00169 Node node = new NodeV (t); 00170 00171 if (m_first == 0) 00172 { 00173 m_last = node; 00174 } 00175 else 00176 { 00177 m_first->m_left = node; 00178 node->m_right = m_first; 00179 } 00180 m_first = node; 00181 } 00182 00183 void push_back (const T& t) 00184 { 00185 Node node = new NodeV (t); 00186 00187 if (m_last == 0) 00188 { 00189 m_first = node; 00190 } 00191 else 00192 { 00193 m_last->m_right = node; 00194 node->m_left = m_last; 00195 } 00196 m_last = node; 00197 } 00198 00199 void pop_front () 00200 { 00201 remove (m_first); 00202 } 00203 00204 void pop_back () 00205 { 00206 remove (m_last); 00207 } 00208 00209 void erase (iterator it) 00210 { 00211 remove (it.get_node ()); 00212 } 00213 00214 void erase (const_iterator it) 00215 { 00216 remove (it.get_node ()); 00217 } 00218 00219 int size () 00220 { 00221 int count = 0; 00222 Node node = m_first; 00223 while (node != 0) 00224 { 00225 node = node->m_right; 00226 count++; 00227 } 00228 00229 return (count); 00230 } 00231 00232 iterator begin () 00233 { 00234 return (iterator (m_first)); 00235 } 00236 00237 iterator last () 00238 { 00239 return (iterator (m_last)); 00240 } 00241 00242 iterator end () 00243 { 00244 iterator it; 00245 return (it); 00246 } 00247 00248 const_iterator begin () const 00249 { 00250 return (const_iterator (m_first)); 00251 } 00252 00253 const_iterator last () const 00254 { 00255 return (const_iterator (m_last)); 00256 } 00257 00258 const_iterator end () const 00259 { 00260 const_iterator it; 00261 return (it); 00262 } 00263 00264 void exchange (iterator it1, iterator it2) 00265 { 00266 if (it1 == it2) return; 00267 00268 Node node1 = it1.get_node (); 00269 if (node1 == 0) return; 00270 Node node2 = it2.get_node (); 00271 if (node2 == 0) return; 00272 00273 Node l1 = node1->m_left; 00274 Node r1 = node1->m_right; 00275 Node l2 = node2->m_left; 00276 Node r2 = node2->m_right; 00277 00278 Node f = m_first; 00279 Node l = m_last; 00280 00281 if ((l2 != 0) && (l2 != node1)) l2->m_right = node1; 00282 if ((r2 != 0) && (r2 != node1)) r2->m_left = node1; 00283 if ((l1 != 0) && (l1 != node2)) r1->m_right = node2; 00284 if ((r1 != 0) && (r1 != node2)) r1->m_left = node2; 00285 00286 node1->m_left = l2; 00287 node1->m_right = r2; 00288 node2->m_left = l1; 00289 node2->m_right = r1; 00290 00291 if (node1 == f) 00292 { 00293 m_first = node2; 00294 } 00295 00296 if (node1 == l) 00297 { 00298 m_last = node2; 00299 } 00300 00301 if (node2 == f) 00302 { 00303 m_first = node1; 00304 } 00305 00306 if (node2 == l) 00307 { 00308 m_last = node1; 00309 } 00310 } 00311 00312 void insert_before (iterator it, const T& t) 00313 { 00314 Node node = it.get_node (); 00315 00316 if (node == 0) 00317 { 00318 push_front (t); 00319 } 00320 else 00321 { 00322 Node new_node = new NodeV (t); 00323 00324 new_node->m_right = node; 00325 new_node->m_left = node->m_left; 00326 00327 if (node->m_left != 0) 00328 { 00329 node->m_left->m_right = new_node; 00330 } 00331 00332 node->m_left = new_node; 00333 00334 if (node == m_first) 00335 { 00336 m_first = new_node; 00337 } 00338 } 00339 } 00340 00341 void insert_after (iterator it, const T& t) 00342 { 00343 Node node = it.get_node (); 00344 00345 if (node == 0) 00346 { 00347 push_back (t); 00348 } 00349 else 00350 { 00351 Node new_node = new NodeV (t); 00352 00353 new_node->m_left = node; 00354 new_node->m_right = node->m_right; 00355 00356 if (node->m_right != 0) 00357 { 00358 node->m_right->m_left = new_node; 00359 } 00360 00361 node->m_right = new_node; 00362 00363 if (node == m_last) 00364 { 00365 m_last = new_node; 00366 } 00367 } 00368 } 00369 00370 void move_to_front (iterator source_it) 00371 { 00372 move_before (source_it, begin ()); 00373 } 00374 00375 void move_to_back (iterator source_it) 00376 { 00377 move_before (source_it, end ()); 00378 } 00379 00380 void move_before (iterator source_it, iterator dest_it) 00381 { 00382 if (source_it == dest_it) return; 00383 00384 Node source = source_it.get_node (); 00385 if (source == 0) return; 00386 00387 Node dest = dest_it.get_node (); 00388 00389 // First remove the source 00390 00391 if (source == m_first) 00392 { 00393 m_first = source->m_right; 00394 } 00395 00396 if (source == m_last) 00397 { 00398 m_last = source->m_left; 00399 } 00400 00401 if (source->m_right != 0) source->m_right->m_left = source->m_left; 00402 if (source->m_left != 0) source->m_left->m_right = source->m_right; 00403 00404 source->m_right = 0; 00405 source->m_left = 0; 00406 00407 if (dest == 0) 00408 { 00409 // = move_to_back 00410 00411 source->m_right = 0; 00412 source->m_left = m_last; 00413 00414 if (m_last != 0) 00415 { 00416 m_last->m_right = source; 00417 } 00418 00419 m_last = source; 00420 00421 if (m_first == 0) m_first = source; 00422 } 00423 else 00424 { 00425 source->m_right = dest; 00426 source->m_left = dest->m_left; 00427 00428 if (dest->m_left != 0) 00429 { 00430 dest->m_left->m_right = source; 00431 } 00432 00433 dest->m_left = source; 00434 00435 if (dest == m_first) 00436 { 00437 m_first = source; 00438 } 00439 } 00440 } 00441 00442 void move_after (iterator source_it, iterator dest_it) 00443 { 00444 if (source_it == dest_it) return; 00445 00446 Node source = source_it.get_node (); 00447 if (source == 0) return; 00448 00449 Node dest = dest_it.get_node (); 00450 00451 // First remove the source 00452 00453 if (source == m_first) 00454 { 00455 m_first = source->m_right; 00456 } 00457 00458 if (source == m_last) 00459 { 00460 m_last = source->m_left; 00461 } 00462 00463 if (source->m_right != 0) source->m_right->m_left = source->m_left; 00464 if (source->m_left != 0) source->m_left->m_right = source->m_right; 00465 00466 source->m_right = 0; 00467 source->m_left = 0; 00468 00469 if (dest == 0) 00470 { 00471 // = move_to_front 00472 00473 source->m_left = 0; 00474 source->m_right = m_first; 00475 00476 if (m_first != 0) 00477 { 00478 m_first->m_left = source; 00479 } 00480 00481 m_first = source; 00482 00483 if (m_last == 0) m_last = source; 00484 } 00485 else 00486 { 00487 source->m_left = dest; 00488 source->m_right = dest->m_right; 00489 00490 if (dest->m_right != 0) 00491 { 00492 dest->m_right->m_left = source; 00493 } 00494 00495 dest->m_right = source; 00496 00497 if (dest == m_last) 00498 { 00499 m_last = source; 00500 } 00501 } 00502 } 00503 00504 private: 00505 void remove (Node node) 00506 { 00507 if (node == 0) return; 00508 00509 if (node == m_first) 00510 { 00511 m_first = node->m_right; 00512 } 00513 00514 if (node == m_last) 00515 { 00516 m_last = node->m_left; 00517 } 00518 00519 if (node->m_right != 0) node->m_right->m_left = node->m_left; 00520 if (node->m_left != 0) node->m_left->m_right = node->m_right; 00521 00522 node->m_right = 0; 00523 node->m_left = 0; 00524 00525 delete node; 00526 } 00527 00528 Node m_first; 00529 Node m_last; 00530 }; 00531 00532 class A 00533 { 00534 public: 00535 A () 00536 { 00537 static int id = 0; 00538 i = id; 00539 id++; 00540 } 00541 00542 ~A () 00543 { 00544 std::cout << "kill A i=" << i << std::endl; 00545 } 00546 00547 int i; 00548 }; 00549 00550 #endif