dlcommon.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /*
  2. * Copyright 2001 Adrian Thurston <thurston@cs.queensu.ca>
  3. */
  4. /* This file is part of Aapl.
  5. *
  6. * Aapl is free software; you can redistribute it and/or modify it under the
  7. * terms of the GNU Lesser General Public License as published by the Free
  8. * Software Foundation; either version 2.1 of the License, or (at your option)
  9. * any later version.
  10. *
  11. * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY
  12. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Aapl; if not, write to the Free Software Foundation, Inc., 59
  18. * Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. /* This header is not wrapped in ifndef becuase it is not intended to
  21. * be included by the user. */
  22. #ifdef AAPL_NAMESPACE
  23. namespace Aapl {
  24. #endif
  25. #if defined( DOUBLELIST_VALUE )
  26. /**
  27. * \brief Double list element for DListVal.
  28. *
  29. * DListValEl stores the type T of DListVal by value.
  30. */
  31. template <class T> struct DListValEl
  32. {
  33. /**
  34. * \brief Construct a DListValEl with a given value.
  35. *
  36. * The only constructor available initializes the value element. This
  37. * enforces that DListVal elements are never created without having their
  38. * value intialzed by the user. T's copy constructor is used to copy the
  39. * value in.
  40. */
  41. DListValEl( const T &val ) : value(val) { }
  42. /**
  43. * \brief Value stored by the list element.
  44. *
  45. * Value is always copied into new list elements using the copy
  46. * constructor.
  47. */
  48. T value;
  49. /**
  50. * \brief List previous pointer.
  51. *
  52. * Points to the previous item in the list. If this is the first item in
  53. * the list, then prev is NULL. If this element is not in a list then
  54. * prev is undefined.
  55. */
  56. DListValEl<T> *prev;
  57. /**
  58. * \brief List next pointer.
  59. *
  60. * Points to the next item in the list. If this is the list item in the
  61. * list, then next is NULL. If this element is not in a list then next is
  62. * undefined.
  63. */
  64. DListValEl<T> *next;
  65. };
  66. #else
  67. #ifndef __AAPL_DOUBLE_LIST_EL
  68. #define __AAPL_DOUBLE_LIST_EL
  69. /**
  70. * \brief Double list element properties.
  71. *
  72. * This class can be inherited to make a class suitable to be a double list
  73. * element. It simply provides the next and previous pointers. An alternative
  74. * is to put the next and previous pointers in the class directly.
  75. */
  76. template <class Element> struct DListEl
  77. {
  78. /**
  79. * \brief List previous pointer.
  80. *
  81. * Points to the previous item in the list. If this is the first item in
  82. * the list, then prev is NULL. If this element is not in a list then
  83. * prev is undefined.
  84. */
  85. Element *prev;
  86. /**
  87. * \brief List next pointer.
  88. *
  89. * Points to the next item in the list. If this is the list item in the
  90. * list, then next is NULL. If this element is not in a list then next is
  91. * undefined.
  92. */
  93. Element *next;
  94. };
  95. #endif /* __AAPL_DOUBLE_LIST_EL */
  96. #endif
  97. /* Doubly Linked List */
  98. template <DLMEL_TEMPDEF> class DList
  99. {
  100. public:
  101. /** \brief Initialize an empty list. */
  102. DList() : head(0), tail(0), listLen(0) {}
  103. /**
  104. * \brief Perform a deep copy of the list.
  105. *
  106. * The elements of the other list are duplicated and put into this list.
  107. * Elements are copied using the copy constructor.
  108. */
  109. DList(const DList &other);
  110. #ifdef DOUBLELIST_VALUE
  111. /**
  112. * \brief Clear the double list contents.
  113. *
  114. * All elements are deleted.
  115. */
  116. ~DList() { empty(); }
  117. /**
  118. * \brief Assign another list into this list using a deep copy.
  119. *
  120. * The elements of the other list are duplicated and put into this list.
  121. * Each list item is created using the copy constructor. If this list
  122. * contains any elements before the copy, they are deleted first.
  123. *
  124. * \returns A reference to this.
  125. */
  126. DList &operator=(const DList &other);
  127. /**
  128. * \brief Transfer the contents of another list into this list.
  129. *
  130. * The elements of the other list moved in. The other list will be empty
  131. * afterwards. If this list contains any elements before the copy, then
  132. * they are deleted.
  133. */
  134. void transfer(DList &other);
  135. #else
  136. /**
  137. * \brief Abandon all elements in the list.
  138. *
  139. * List elements are not deleted.
  140. */
  141. ~DList() {}
  142. /**
  143. * \brief Perform a deep copy of the list.
  144. *
  145. * The elements of the other list are duplicated and put into this list.
  146. * Each list item is created using the copy constructor. If this list
  147. * contains any elements before the copy, they are abandoned.
  148. *
  149. * \returns A reference to this.
  150. */
  151. DList &operator=(const DList &other);
  152. /**
  153. * \brief Transfer the contents of another list into this list.
  154. *
  155. * The elements of the other list moved in. The other list will be empty
  156. * afterwards. If this list contains any elements before the copy, they
  157. * are abandoned.
  158. */
  159. void transfer(DList &other);
  160. #endif
  161. #ifdef DOUBLELIST_VALUE
  162. /**
  163. * \brief Make a new element and prepend it to the front of the list.
  164. *
  165. * The item is copied into the new element using the copy constructor.
  166. * Equivalent to list.addBefore(list.head, item).
  167. */
  168. void prepend(const T &item);
  169. /**
  170. * \brief Make a new element and append it to the end of the list.
  171. *
  172. * The item is copied into the new element using the copy constructor.
  173. * Equivalent to list.addAfter(list.tail, item).
  174. */
  175. void append(const T &item);
  176. /**
  177. * \brief Make a new element and insert it immediately after an element in
  178. * the list.
  179. *
  180. * The item is copied into the new element using the copy constructor. If
  181. * prev_el is NULL then the new element is prepended to the front of the
  182. * list. If prev_el is not already in the list then undefined behaviour
  183. * results. Equivalent to list.addAfter(prev_el, new DListValEl(item)).
  184. */
  185. void addAfter(Element *prev_el, const T &item);
  186. /**
  187. * \brief Make a new element and insert it immediately before an element
  188. * in the list.
  189. *
  190. * The item is copied into the new element using the copy construcotor. If
  191. * next_el is NULL then the new element is appended to the end of the
  192. * list. If next_el is not already in the list then undefined behaviour
  193. * results. Equivalent to list.addBefore(next_el, new DListValEl(item)).
  194. */
  195. void addBefore(Element *next_el, const T &item);
  196. #endif
  197. /**
  198. * \brief Prepend a single element to the front of the list.
  199. *
  200. * If new_el is already an element of some list, then undefined behaviour
  201. * results. Equivalent to list.addBefore(list.head, new_el).
  202. */
  203. void prepend(Element *new_el) { addBefore(head, new_el); }
  204. /**
  205. * \brief Append a single element to the end of the list.
  206. *
  207. * If new_el is alreay an element of some list, then undefined behaviour
  208. * results. Equivalent to list.addAfter(list.tail, new_el).
  209. */
  210. void append(Element *new_el) { addAfter(tail, new_el); }
  211. /**
  212. * \brief Prepend an entire list to the beginning of this list.
  213. *
  214. * All items are moved, not copied. Afterwards, the other list is emtpy.
  215. * All items are prepended at once, so this is an O(1) operation.
  216. * Equivalent to list.addBefore(list.head, dl).
  217. */
  218. void prepend(DList &dl) { addBefore(head, dl); }
  219. /**
  220. * \brief Append an entire list to the end of the list.
  221. *
  222. * All items are moved, not copied. Afterwards, the other list is empty.
  223. * All items are appened at once, so this is an O(1) operation.
  224. * Equivalent to list.addAfter(list.tail, dl).
  225. */
  226. void append(DList &dl) { addAfter(tail, dl); }
  227. void addAfter(Element *prev_el, Element *new_el);
  228. void addBefore(Element *next_el, Element *new_el);
  229. void addAfter(Element *prev_el, DList &dl);
  230. void addBefore(Element *next_el, DList &dl);
  231. /**
  232. * \brief Detach the head of the list
  233. *
  234. * The element detached is not deleted. If there is no head of the list
  235. * (the list is empty) then undefined behaviour results. Equivalent to
  236. * list.detach(list.head).
  237. *
  238. * \returns The element detached.
  239. */
  240. Element *detachFirst() { return detach(head); }
  241. /**
  242. * \brief Detach the tail of the list
  243. *
  244. * The element detached is not deleted. If there is no tail of the list
  245. * (the list is empty) then undefined behaviour results. Equivalent to
  246. * list.detach(list.tail).
  247. *
  248. * \returns The element detached.
  249. */
  250. Element *detachLast() { return detach(tail); }
  251. /* Detaches an element from the list. Does not free any memory. */
  252. Element *detach(Element *el);
  253. /**
  254. * \brief Detach and delete the first element in the list.
  255. *
  256. * If there is no first element (the list is empty) then undefined
  257. * behaviour results. Equivalent to delete list.detach(list.head);
  258. */
  259. void removeFirst() { delete detach( head ); }
  260. /**
  261. * \brief Detach and delete the last element in the list.
  262. *
  263. * If there is no last element (the list is emtpy) then undefined
  264. * behaviour results. Equivalent to delete list.detach(list.tail);
  265. */
  266. void removeLast() { delete detach( tail ); }
  267. /**
  268. * \brief Detach and delete an element from the list.
  269. *
  270. * If the element is not in the list, then undefined behaviour results.
  271. * Equivalent to delete list.detach(el);
  272. */
  273. void remove(Element *el) { delete detach( el ); }
  274. void empty();
  275. void abandon();
  276. /** \brief The number of elements in the list. */
  277. long length() const { return listLen; }
  278. /** \brief Head and tail of the linked list. */
  279. Element *head, *tail;
  280. /** \brief The number of element in the list. */
  281. long listLen;
  282. /* Convenience access. */
  283. long size() const { return listLen; }
  284. /* Forward this so a ref can be used. */
  285. struct Iter;
  286. /* Class for setting the iterator. */
  287. struct IterFirst { IterFirst( const DList &l ) : l(l) { } const DList &l; };
  288. struct IterLast { IterLast( const DList &l ) : l(l) { } const DList &l; };
  289. struct IterNext { IterNext( const Iter &i ) : i(i) { } const Iter &i; };
  290. struct IterPrev { IterPrev( const Iter &i ) : i(i) { } const Iter &i; };
  291. /**
  292. * \brief Double List Iterator.
  293. * \ingroup iterators
  294. */
  295. struct Iter
  296. {
  297. /* Default construct. */
  298. Iter() : ptr(0) { }
  299. /* Construct from a double list. */
  300. Iter( const DList &dl ) : ptr(dl.head) { }
  301. Iter( Element *el ) : ptr(el) { }
  302. Iter( const IterFirst &dlf ) : ptr(dlf.l.head) { }
  303. Iter( const IterLast &dll ) : ptr(dll.l.tail) { }
  304. Iter( const IterNext &dln ) : ptr(dln.i.ptr->BASE_EL(next)) { }
  305. Iter( const IterPrev &dlp ) : ptr(dlp.i.ptr->BASE_EL(prev)) { }
  306. /* Assign from a double list. */
  307. Iter &operator=( const DList &dl ) { ptr = dl.head; return *this; }
  308. Iter &operator=( Element *el ) { ptr = el; return *this; }
  309. Iter &operator=( const IterFirst &af ) { ptr = af.l.head; return *this; }
  310. Iter &operator=( const IterLast &al ) { ptr = al.l.tail; return *this; }
  311. Iter &operator=( const IterNext &an ) { ptr = an.i.ptr->BASE_EL(next); return *this; }
  312. Iter &operator=( const IterPrev &ap ) { ptr = ap.i.ptr->BASE_EL(prev); return *this; }
  313. /** \brief Less than end? */
  314. bool lte() const { return ptr != 0; }
  315. /** \brief At end? */
  316. bool end() const { return ptr == 0; }
  317. /** \brief Greater than beginning? */
  318. bool gtb() const { return ptr != 0; }
  319. /** \brief At beginning? */
  320. bool beg() const { return ptr == 0; }
  321. /** \brief At first element? */
  322. bool first() const { return ptr && ptr->BASE_EL(prev) == 0; }
  323. /** \brief At last element? */
  324. bool last() const { return ptr && ptr->BASE_EL(next) == 0; }
  325. /** \brief Implicit cast to Element*. */
  326. operator Element*() const { return ptr; }
  327. /** \brief Dereference operator returns Element&. */
  328. Element &operator *() const { return *ptr; }
  329. /** \brief Arrow operator returns Element*. */
  330. Element *operator->() const { return ptr; }
  331. /** \brief Move to next item. */
  332. inline Element *operator++() { return ptr = ptr->BASE_EL(next); }
  333. /** \brief Move to next item. */
  334. inline Element *increment() { return ptr = ptr->BASE_EL(next); }
  335. /** \brief Move to next item. */
  336. inline Element *operator++(int);
  337. /** \brief Move to previous item. */
  338. inline Element *operator--() { return ptr = ptr->BASE_EL(prev); }
  339. /** \brief Move to previous item. */
  340. inline Element *decrement() { return ptr = ptr->BASE_EL(prev); }
  341. /** \brief Move to previous item. */
  342. inline Element *operator--(int);
  343. /** \brief Return the next item. Does not modify this. */
  344. inline IterNext next() const { return IterNext(*this); }
  345. /** \brief Return the prev item. Does not modify this. */
  346. inline IterPrev prev() const { return IterPrev(*this); }
  347. /** \brief The iterator is simply a pointer. */
  348. Element *ptr;
  349. };
  350. /** \brief Return first element. */
  351. IterFirst first() { return IterFirst(*this); }
  352. /** \brief Return last element. */
  353. IterLast last() { return IterLast(*this); }
  354. };
  355. /* Copy constructor, does a deep copy of other. */
  356. template <DLMEL_TEMPDEF> DList<DLMEL_TEMPUSE>::
  357. DList(const DList<DLMEL_TEMPUSE> &other) :
  358. head(0), tail(0), listLen(0)
  359. {
  360. Element *el = other.head;
  361. while( el != 0 ) {
  362. append( new Element(*el) );
  363. el = el->BASE_EL(next);
  364. }
  365. }
  366. #ifdef DOUBLELIST_VALUE
  367. /* Assignement operator does deep copy. */
  368. template <DLMEL_TEMPDEF> DList<DLMEL_TEMPUSE> &DList<DLMEL_TEMPUSE>::
  369. operator=(const DList &other)
  370. {
  371. /* Free the old list. The value list assumes items were allocated on the
  372. * heap by itself. */
  373. empty();
  374. Element *el = other.head;
  375. while( el != 0 ) {
  376. append( new Element(*el) );
  377. el = el->BASE_EL(next);
  378. }
  379. return *this;
  380. }
  381. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  382. transfer(DList &other)
  383. {
  384. /* Free the old list. The value list assumes items were allocated on the
  385. * heap by itself. */
  386. empty();
  387. head = other.head;
  388. tail = other.tail;
  389. listLen = other.listLen;
  390. other.abandon();
  391. }
  392. #else
  393. /* Assignement operator does deep copy. */
  394. template <DLMEL_TEMPDEF> DList<DLMEL_TEMPUSE> &DList<DLMEL_TEMPUSE>::
  395. operator=(const DList &other)
  396. {
  397. Element *el = other.head;
  398. while( el != 0 ) {
  399. append( new Element(*el) );
  400. el = el->BASE_EL(next);
  401. }
  402. return *this;
  403. }
  404. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  405. transfer(DList &other)
  406. {
  407. head = other.head;
  408. tail = other.tail;
  409. listLen = other.listLen;
  410. other.abandon();
  411. }
  412. #endif
  413. #ifdef DOUBLELIST_VALUE
  414. /* Prepend a new item. Inlining this bloats the caller with new overhead. */
  415. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  416. prepend(const T &item)
  417. {
  418. addBefore(head, new Element(item));
  419. }
  420. /* Append a new item. Inlining this bloats the caller with the new overhead. */
  421. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  422. append(const T &item)
  423. {
  424. addAfter(tail, new Element(item));
  425. }
  426. /* Add a new item after a prev element. Inlining this bloats the caller with
  427. * the new overhead. */
  428. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  429. addAfter(Element *prev_el, const T &item)
  430. {
  431. addAfter(prev_el, new Element(item));
  432. }
  433. /* Add a new item before a next element. Inlining this bloats the caller with
  434. * the new overhead. */
  435. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  436. addBefore(Element *next_el, const T &item)
  437. {
  438. addBefore(next_el, new Element(item));
  439. }
  440. #endif
  441. /*
  442. * The larger iterator operators.
  443. */
  444. /* Postfix ++ */
  445. template <DLMEL_TEMPDEF> Element *DList<DLMEL_TEMPUSE>::Iter::
  446. operator++(int)
  447. {
  448. Element *rtn = ptr;
  449. ptr = ptr->BASE_EL(next);
  450. return rtn;
  451. }
  452. /* Postfix -- */
  453. template <DLMEL_TEMPDEF> Element *DList<DLMEL_TEMPUSE>::Iter::
  454. operator--(int)
  455. {
  456. Element *rtn = ptr;
  457. ptr = ptr->BASE_EL(prev);
  458. return rtn;
  459. }
  460. /**
  461. * \brief Insert an element immediately after an element in the list.
  462. *
  463. * If prev_el is NULL then new_el is prepended to the front of the list. If
  464. * prev_el is not in the list or if new_el is already in a list, then
  465. * undefined behaviour results.
  466. */
  467. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  468. addAfter(Element *prev_el, Element *new_el)
  469. {
  470. /* Set the previous pointer of new_el to prev_el. We do
  471. * this regardless of the state of the list. */
  472. new_el->BASE_EL(prev) = prev_el;
  473. /* Set forward pointers. */
  474. if (prev_el == 0) {
  475. /* There was no prev_el, we are inserting at the head. */
  476. new_el->BASE_EL(next) = head;
  477. head = new_el;
  478. }
  479. else {
  480. /* There was a prev_el, we can access previous next. */
  481. new_el->BASE_EL(next) = prev_el->BASE_EL(next);
  482. prev_el->BASE_EL(next) = new_el;
  483. }
  484. /* Set reverse pointers. */
  485. if (new_el->BASE_EL(next) == 0) {
  486. /* There is no next element. Set the tail pointer. */
  487. tail = new_el;
  488. }
  489. else {
  490. /* There is a next element. Set it's prev pointer. */
  491. new_el->BASE_EL(next)->BASE_EL(prev) = new_el;
  492. }
  493. /* Update list length. */
  494. listLen++;
  495. }
  496. /**
  497. * \brief Insert an element immediatly before an element in the list.
  498. *
  499. * If next_el is NULL then new_el is appended to the end of the list. If
  500. * next_el is not in the list or if new_el is already in a list, then
  501. * undefined behaviour results.
  502. */
  503. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  504. addBefore(Element *next_el, Element *new_el)
  505. {
  506. /* Set the next pointer of the new element to next_el. We do
  507. * this regardless of the state of the list. */
  508. new_el->BASE_EL(next) = next_el;
  509. /* Set reverse pointers. */
  510. if (next_el == 0) {
  511. /* There is no next elememnt. We are inserting at the tail. */
  512. new_el->BASE_EL(prev) = tail;
  513. tail = new_el;
  514. }
  515. else {
  516. /* There is a next element and we can access next's previous. */
  517. new_el->BASE_EL(prev) = next_el->BASE_EL(prev);
  518. next_el->BASE_EL(prev) = new_el;
  519. }
  520. /* Set forward pointers. */
  521. if (new_el->BASE_EL(prev) == 0) {
  522. /* There is no previous element. Set the head pointer.*/
  523. head = new_el;
  524. }
  525. else {
  526. /* There is a previous element, set it's next pointer to new_el. */
  527. new_el->BASE_EL(prev)->BASE_EL(next) = new_el;
  528. }
  529. /* Update list length. */
  530. listLen++;
  531. }
  532. /**
  533. * \brief Insert an entire list immediatly after an element in this list.
  534. *
  535. * Elements are moved, not copied. Afterwards, the other list is empty. If
  536. * prev_el is NULL then the elements are prepended to the front of the list.
  537. * If prev_el is not in the list then undefined behaviour results. All
  538. * elements are inserted into the list at once, so this is an O(1) operation.
  539. */
  540. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  541. addAfter( Element *prev_el, DList<DLMEL_TEMPUSE> &dl )
  542. {
  543. /* Do not bother if dl has no elements. */
  544. if ( dl.listLen == 0 )
  545. return;
  546. /* Set the previous pointer of dl.head to prev_el. We do
  547. * this regardless of the state of the list. */
  548. dl.head->BASE_EL(prev) = prev_el;
  549. /* Set forward pointers. */
  550. if (prev_el == 0) {
  551. /* There was no prev_el, we are inserting at the head. */
  552. dl.tail->BASE_EL(next) = head;
  553. head = dl.head;
  554. }
  555. else {
  556. /* There was a prev_el, we can access previous next. */
  557. dl.tail->BASE_EL(next) = prev_el->BASE_EL(next);
  558. prev_el->BASE_EL(next) = dl.head;
  559. }
  560. /* Set reverse pointers. */
  561. if (dl.tail->BASE_EL(next) == 0) {
  562. /* There is no next element. Set the tail pointer. */
  563. tail = dl.tail;
  564. }
  565. else {
  566. /* There is a next element. Set it's prev pointer. */
  567. dl.tail->BASE_EL(next)->BASE_EL(prev) = dl.tail;
  568. }
  569. /* Update the list length. */
  570. listLen += dl.listLen;
  571. /* Empty out dl. */
  572. dl.head = dl.tail = 0;
  573. dl.listLen = 0;
  574. }
  575. /**
  576. * \brief Insert an entire list immediately before an element in this list.
  577. *
  578. * Elements are moved, not copied. Afterwards, the other list is empty. If
  579. * next_el is NULL then the elements are appended to the end of the list. If
  580. * next_el is not in the list then undefined behaviour results. All elements
  581. * are inserted at once, so this is an O(1) operation.
  582. */
  583. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::
  584. addBefore( Element *next_el, DList<DLMEL_TEMPUSE> &dl )
  585. {
  586. /* Do not bother if dl has no elements. */
  587. if ( dl.listLen == 0 )
  588. return;
  589. /* Set the next pointer of dl.tail to next_el. We do
  590. * this regardless of the state of the list. */
  591. dl.tail->BASE_EL(next) = next_el;
  592. /* Set reverse pointers. */
  593. if (next_el == 0) {
  594. /* There is no next elememnt. We are inserting at the tail. */
  595. dl.head->BASE_EL(prev) = tail;
  596. tail = dl.tail;
  597. }
  598. else {
  599. /* There is a next element and we can access next's previous. */
  600. dl.head->BASE_EL(prev) = next_el->BASE_EL(prev);
  601. next_el->BASE_EL(prev) = dl.tail;
  602. }
  603. /* Set forward pointers. */
  604. if (dl.head->BASE_EL(prev) == 0) {
  605. /* There is no previous element. Set the head pointer.*/
  606. head = dl.head;
  607. }
  608. else {
  609. /* There is a previous element, set it's next pointer to new_el. */
  610. dl.head->BASE_EL(prev)->BASE_EL(next) = dl.head;
  611. }
  612. /* Update list length. */
  613. listLen += dl.listLen;
  614. /* Empty out dl. */
  615. dl.head = dl.tail = 0;
  616. dl.listLen = 0;
  617. }
  618. /**
  619. * \brief Detach an element from the list.
  620. *
  621. * The element is not deleted. If the element is not in the list, then
  622. * undefined behaviour results.
  623. *
  624. * \returns The element detached.
  625. */
  626. template <DLMEL_TEMPDEF> Element *DList<DLMEL_TEMPUSE>::
  627. detach(Element *el)
  628. {
  629. /* Set forward pointers to skip over el. */
  630. if (el->BASE_EL(prev) == 0)
  631. head = el->BASE_EL(next);
  632. else {
  633. el->BASE_EL(prev)->BASE_EL(next) =
  634. el->BASE_EL(next);
  635. }
  636. /* Set reverse pointers to skip over el. */
  637. if (el->BASE_EL(next) == 0)
  638. tail = el->BASE_EL(prev);
  639. else {
  640. el->BASE_EL(next)->BASE_EL(prev) =
  641. el->BASE_EL(prev);
  642. }
  643. /* Update List length and return element we detached. */
  644. listLen--;
  645. return el;
  646. }
  647. /**
  648. * \brief Clear the list by deleting all elements.
  649. *
  650. * Each item in the list is deleted. The list is reset to its initial state.
  651. */
  652. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::empty()
  653. {
  654. Element *nextToGo = 0, *cur = head;
  655. while (cur != 0)
  656. {
  657. nextToGo = cur->BASE_EL(next);
  658. delete cur;
  659. cur = nextToGo;
  660. }
  661. head = tail = 0;
  662. listLen = 0;
  663. }
  664. /**
  665. * \brief Clear the list by forgetting all elements.
  666. *
  667. * All elements are abandoned, not deleted. The list is reset to it's initial
  668. * state.
  669. */
  670. template <DLMEL_TEMPDEF> void DList<DLMEL_TEMPUSE>::abandon()
  671. {
  672. head = tail = 0;
  673. listLen = 0;
  674. }
  675. #ifdef AAPL_NAMESPACE
  676. }
  677. #endif