TBCI Numerical high perf. C++ Library  2.8.0
list.h
Go to the documentation of this file.
1 
4 /* $Id: list.h,v 1.9.2.22 2019/05/28 11:13:02 garloff Exp $
5  *
6  * Copyright 1996--98 Kurt Garloff <kurt@garloff.de>
7  * This software is protected by the GNU LGPL
8  */
9 
10 /*
11  * TODO:
12  * - Implementation of treedel();
13  */
14 
15 
16 #ifndef TBCI_LIST_H
17 #define TBCI_LIST_H
18 
19 #include "tbci/basics.h"
20 #ifndef LIST_LANG_C
21 # include <iostream>
22 #else
23 # include <stdio.h>
24 #endif
25 
26 #ifdef PRAGMA_I
27 # pragma interface "list.h"
28 #endif
29 
30 #define NULTP (T*)0
31 
32 #ifndef STD__
33 # define STD__ std::
34 #endif
35 
36 #ifdef NAMESPACE_TBCI
38 #endif
39 
43 template <typename T>
44 class ListItem {
45  private:
46  public:
47  T* data;
50  public:
51  ListItem() { data = new T; }
52  ~ListItem() { /* STD__ cerr << "\ndelete ListItem!\n";*/ delete data; }
53 } ;
54 
55 
56 // Declare some (or all?) members static (?)
57 // We can only handle one list of each type then, cant we (?)
58 
59 template <typename T> class List;
60 /* Iterators */
61 template <typename T>
63 {
64  protected:
66  long currnr;
67  unsigned long vers;
68  const List<T> *lst;
69  int dir;
70  public:
71  // ctors
72  ListIterator (const List<T>& _list, T* dataptr = 0);
73  ListIterator (const List<T>& _list, ListItem<T>* li = 0);
74  ListIterator (const List<T>& _list, ListItem<T>* li,
75  const long nr);
77  curr (li.curr), currnr (li.currnr),
78  vers (li.vers), lst (li.lst), dir(li.dir) {}
79  // assignment
81  // get no
82  long getnr ();
83  // dereference
84  T* operator * () const;
85  operator bool () const;
86  // (pre)increment/decrement
89  // comparison
90  bool operator == (const ListIterator<T>& li) const;
91  bool operator != (const ListIterator<T>& li) const;
92  bool operator < (const ListIterator<T>& li) const;
93  bool operator > (const ListIterator<T>& li) const;
94  bool operator <= (const ListIterator<T>& li) const;
95  bool operator >= (const ListIterator<T>& li) const;
96 
97 } ;
98 
99 template <typename T>
100 ListIterator<T>::ListIterator (const List<T>& _list, T* dataptr/* = 0*/)
101  : vers (_list.vers), lst (&_list), dir (1)
102 {
103  if (dataptr)
104  _list.setcurr (dataptr);
105  curr = _list.getcurr ();
106  currnr = _list.getcurrnr ();
107 }
108 
109 template <typename T>
111  : vers (_list.vers), lst (&_list), dir (1)
112 {
113  if (li)
114  _list.setcurr (li->data);
115  curr = _list.getcurr ();
116  currnr = (long)_list.getcurrnr ();
117 }
118 
119 template <typename T>
121  const long nr)
122  : curr (li), currnr (nr), vers (_list.vers), lst (&_list), dir (1)
123 {}
124 
125 template <typename T>
127 {
128  curr = li.curr; currnr = li.currnr;
129  vers = li.vers; lst = li.lst;
130  dir = 1;
131  return *this;
132 }
133 
134 template <typename T>
136 {
137  if (vers != lst->vers) {
138  currnr = lst->getnr (curr->data);
139  vers = lst->vers;
140  }
141  return currnr;
142 }
143 
144 template <typename T>
146 {
147  return curr->data;
148 }
149 
150 template <typename T>
152 {
153  if (curr)
154  return true;
155  else
156  return false;
157 }
158 
159 
160 template <typename T>
162 {
163  if (curr)
164  if (dir > 0) {
165  curr = curr->next; currnr++;
166  } else {
167  curr = curr->prev; currnr--;
168  }
169  else
170  if (dir > 0) {
171  if (currnr <= 0) {
172  curr = lst->root;
173  currnr = 1;
174  }
175  } else {
176  if (currnr > 0 /*lst->count*/) {
177  curr = lst->last;
178  currnr = lst->count;
179  }
180  }
181  return (*this);
182 }
183 
184 template <typename T>
186 {
187  if (curr)
188  if (dir > 0) {
189  curr = curr->prev; currnr--;
190  } else {
191  curr = curr->next; currnr++;
192  }
193  else
194  if (dir > 0) {
195  if (currnr > 0 /*lst->count*/) {
196  curr = lst->last;
197  currnr = lst->count;
198  }
199  } else {
200  if (currnr <= 0) {
201  curr = lst->root;
202  currnr = 1;
203  }
204  }
205  return (*this);
206 }
207 
208 template <typename T>
209 inline bool ListIterator<T>::operator == (const ListIterator<T>& li) const
210 {
211  if (lst == li.lst /*&& dir == li.dir*/ && currnr == li.currnr)
212  return true;
213  else
214  return false;
215 }
216 
217 template <typename T>
218 inline bool ListIterator<T>::operator != (const ListIterator<T>& li) const
219 {
220  return !(*this == li);
221 }
222 
223 template <typename T>
224 inline bool ListIterator<T>::operator < (const ListIterator<T>& li) const
225 {
226  if (lst != li.lst /*|| dir != li.dir*/)
227  abort ();
228  return (dir * currnr < li.dir * li.currnr);
229 }
230 
231 template <typename T>
232 inline bool ListIterator<T>::operator <= (const ListIterator<T>& li) const
233 {
234  if (lst != li.lst /*|| dir != li.dir*/)
235  abort ();
236  return (dir * currnr <= li.dir * li.currnr);
237 }
238 
239 template <typename T>
240 inline bool ListIterator<T>::operator > (const ListIterator<T>& li) const
241 {
242  return !(*this <= li);
243 }
244 
245 template <typename T>
246 inline bool ListIterator<T>::operator >= (const ListIterator<T>& li) const
247 {
248  return !(*this < li);
249 }
250 
251 
252 template <typename T>
253 class ListRIterator : public ListIterator<T>
254 {
255  protected:
256  using ListIterator<T>::dir;
257  using ListIterator<T>::curr;
259  using ListIterator<T>::vers;
260  using ListIterator<T>::lst;
261  public:
262  ListRIterator (const List<T>& _list, T* dataptr)
263  : ListIterator<T> (_list, dataptr) { dir = -1; }
264  ListRIterator (const List<T>& _list, ListItem<T>* li)
265  : ListIterator<T> (_list, li) { dir = -1; }
266  ListRIterator (const List<T>& _list, ListItem<T>* li,
267  const unsigned long nr)
268  : ListIterator<T> (_list, li, nr) { dir = -1; }
269  /* ListRIterator (const ListIterator<T>& li)
270  : ListIterator<T> (li) { dir = -1; } */
272 } ;
273 
274 template <typename T>
276 {
277  curr = li.curr; currnr = li.currnr;
278  vers = li.vers; lst = li.lst;
279  dir = 1;
280  return *this;
281 }
282 
288 template <typename T>
289 class List {
290  protected:
291  mutable ListItem<T> *curr;
292  unsigned long count;
293  mutable unsigned long currnr;
294  unsigned long vers;
295 
296  void checklast ();
297  ListItem<T> *app ();
298 
299  protected:
303 
304  public:
305  friend class ListIterator<T>;
307  friend class ListRIterator<T>;
309 
310  List () : curr(NULL), count(0), currnr(0),
311  vers(0), root(NULL), last(NULL), detached(NULL) {}
312  List (const List<T>&);
313  List<T>& operator = (const List<T>&);
314  List<T>& alias (const List<T>&);
315 
316  iterator begin () const;
317  iterator end () const;
318  riterator rbegin () const;
319  riterator rend () const;
320 
321  T* append ();
322  T* append (T*);
323  void erase (T*);
324  void deltree (T*); //Deletes List from item to end
325  void deltree ();
326  //void treedel (T*)
327  //void treedel ();
328  /* Never do call by value with List<xy> argument, ~List () would be called ! */
329  ~List () { deltree (); }
330 
331  T* getfirst () const;
332  T* getlast () const;
333  T* getcurr () const;
334  T* getnext () const;
335  T* getprev () const;
336  T* setfirst () const;
337  T* setlast () const;
338  T* setnext () const;
339  T* setprev () const;
340  T* inscurr ();
341  T* inscurr (T*);
342  T* delcurr ();
343  T* detachcurr ();
344 
345  unsigned long getlength () const;
346  unsigned long size () const;
348  unsigned long getcurrnr () const;
349  unsigned long getnr (const T*) const;
350  unsigned long getnr () const;
351  T* getbynr (long) const;
352 
353  T* setcurrnr (const unsigned long) const;
354  T* setcurr (const T* rec) const { setcurrnr (getnr (rec)); return getcurr (); }
355 
356  void dumpList () const;
357 } ;
358 
359 // Implementation
360 
361 template <typename T>
362 inline void List<T>::checklast ()
363 {
364  while (last -> next != NULL) {
365  last = last -> next; count++;
366  }
367 } //paranoia
368 
369 // copy the List of pointers and the data itsself
370 template <typename T>
372 {
373  ListItem<T>* tmp = l.root; vers = l.vers;
374  root = NULL; last = NULL; curr = NULL; detached = NULL; count = 0;
375  while (tmp) {
376  curr = app();
377  //curr->data = tmp->data;
378  *(curr->data) = *(tmp->data);
379  tmp = tmp->next;
380  }
381 }
382 
383 // assignment
384 template <typename T>
386 {
387  deltree ();
388  ListItem<T>* tmp = l.root;
389  root = NULL; last = NULL; curr = NULL; detached = NULL;
390  count = 0; vers++;
391  while (tmp) {
392  curr = app();
393  //curr->data = tmp->data;
394  *(curr->data) = *(tmp->data);
395  tmp = tmp->next;
396  }
397  return *this;
398 }
399 
400 // aliasing
401 template <typename T>
403 {
404  deltree ();
405  ListItem<T>* tmp = l.root; vers = l.vers;
406  root = NULL; last = NULL; curr = NULL; detached = NULL; count = 0;
407  while (tmp) {
408  curr = app();
409  curr->data = tmp->data;
410  tmp = tmp->next;
411  }
412  return *this;
413 }
414 
415 
416 template <typename T>
418 {
419  count++; currnr = count; vers++;
420  if (!root) {
421  curr = new ListItem<T>;
422  curr->prev = NULL; curr->next = NULL;
423  root = curr; last = curr;
424  return curr;
425  } else {
426  //checklast();
427  curr = new ListItem<T>;
428  curr->prev = last; curr->next = NULL;
429  last->next = curr; last = curr;
430  return curr;
431  }
432 }
433 
434 
435 template <typename T>
436 inline T* List<T>::append ()
437 {
438  return app()->data;
439 }
440 
441 template <typename T>
442 inline T* List<T>::append (T* data)
443 {
444  T *tmp = this->append ();
445  *tmp = *data; return tmp;
446 }
447 
448 
449 template <typename T>
451 {
452  if (!curr) return append(); //append and insert is equal for void Lists
453  count++; vers++;
454  if (!(curr->prev)) { //Insert at the beginning of the List
455  curr = new ListItem<T>; curr->prev = NULL; curr->next = root;
456  root->prev = curr; root = curr;
457  } else {
458  ListItem<T> *ins = new ListItem<T>;
459  ins->next = curr; ins->prev = curr->prev;
460  ins->prev->next = ins; curr->prev = ins;
461  curr = ins;
462  }
463  return curr->data;
464 }
465 
466 template <typename T>
467 inline T* List<T>::inscurr (T* elem)
468 {
469  T* ptr = inscurr ();
470  *ptr = *elem;
471  return ptr;
472 }
473 
474 template <typename T>
476 {
477  if (curr == NULL) return NULTP;
478  count--; vers++;
479  if (curr->next == NULL) { // curr == last
480  currnr = count;
481  if (curr->prev == NULL) { // curr == root
482  delete curr;
483  root=NULL; curr=NULL; last=NULL; /*count=0;*/
484  return NULTP;
485  } else {
486  last = curr->prev;
487  curr->prev->next = NULL;
488  delete curr;
489  curr = NULL;
490  return NULTP;
491  }
492  } else {
493  if (curr->prev == NULL) { // curr == root
494  curr = curr->next;
495  delete curr->prev;
496  curr->prev = NULL;
497  root = curr;
498  } else {
499  curr->prev->next = curr->next;
500  curr->next->prev = curr->prev;
501  ListItem<T> *del = curr;
502  curr = curr->next;
503  delete del;
504  }
505  }
506  return curr->data;
507 }
508 
509 template <typename T>
511 {
512  if (curr == NULL) return NULTP;
513  count--; vers++;
514  if (curr->next == NULL) { // curr == last
515  currnr = count;
516  if (curr->prev == NULL) { // curr == root
517  //if (detached)
518  // detached->prev = curr;
519  curr->next = detached;
520  detached = curr; //detached->prev = NULL;
521  root=NULL; curr=NULL; last=NULL; /*count=0;*/
522  return NULTP;
523  } else {
524  last = curr->prev;
525  curr->prev->next = NULL;
526  //if (detached)
527  // detached->prev = curr;
528  curr->next = detached;
529  detached = curr; //detached->prev = NULL;
530  curr = NULL;
531  return NULTP;
532  }
533  } else {
534  if (curr->prev == NULL) { // curr == root
535  curr = curr->next;
536  //if (detached)
537  // detached->prev = curr->prev;
538  curr->prev->next = detached;
539  detached = curr->prev; //detached->prev = NULL;
540  curr->prev = NULL;
541  root = curr;
542  } else {
543  curr->prev->next = curr->next;
544  curr->next->prev = curr->prev;
545  ListItem<T> *del = curr;
546  curr = curr->next;
547  //if (detached)
548  // detached->prev = del;
549  del->next = detached;
550  detached = del; //detached->prev = NULL;
551  }
552  }
553  return curr->data;
554 }
555 
557 template <typename T>
558 void List<T>::deltree (T* delroot)
559 {
560  if (last == NULL) return;
561  //checklast();
562  vers++;
563  //STD__ cerr << "\ndeltree called!\n";
564  while (!(last->data == delroot)) {
565  count--; currnr = count;
566  curr = last->prev; delete last; last = curr;
567  if (curr == NULL) { //check should not be necessary ...
568 #ifdef LIST_LANG_C
569  fprintf(stderr,"List::deltree: error: wrong pointer provided !\n");
570 #else
571  STD__ cerr << "List::deltree: error: wrong pointer provided !" << '\n';
572 #endif
573  root = NULL; return;
574  }
575  else curr->next = NULL;
576  }
577  //delete last one, curr->data == delroot
578  count --; currnr = count;
579  curr = last->prev; delete last; last = curr;
580  if (curr == NULL) root = NULL;
581  else curr->next = NULL;
582 }
583 
584 //template <typename T>
585 //void List<T>::treedel(T* rootdel)
586 
587 template <typename T>
588 inline void List<T>::deltree ()
589 {
590  if (root != NULL)
591  deltree (root -> data);
592  while (detached) {
593  ListItem<T>* del = detached->next;
594  delete detached;
595  detached = del;
596  }
597 }
598 
599 //template <typename T>
600 //void List<T>::treedel()
601 
602 template <typename T>
603 inline typename List<T>::iterator List<T>::begin () const
604 { return ListIterator<T> (*this, root, (long)1); }
605 template <typename T>
606 inline typename List<T>::iterator List<T>::end () const
607 { return ListIterator<T> (*this, 0, (long)count+1); }
608 template <typename T>
609 inline typename List<T>::riterator List<T>::rbegin () const
610 { return ListRIterator<T> (*this, last, (long)count); }
611 template <typename T>
612 inline typename List<T>::riterator List<T>::rend () const
613 { return ListRIterator<T> (*this, 0, (long)0); }
614 
615 
616 template <typename T>
617 inline T* List<T>::getfirst () const
618 { return (root?root->data:NULTP); }
619 
620 template <typename T>
621 inline T* List<T>::getlast () const
622 { /*checklast();*/ return (last?last->data:NULTP); }
623 
624 template <typename T>
625 inline T* List<T>::getcurr () const
626 { return (curr?curr->data:NULTP); }
627 
628 template <typename T>
629 inline T* List<T>::getnext () const
630 { if (!curr || !curr->next) return NULTP;
631  else return curr->next->data; }
632 
633 template <typename T>
634 inline T* List<T>::getprev () const
635 { if (!curr || !curr->prev) return NULTP;
636  else return curr->prev->data; }
637 
638 template <typename T>
639 inline T* List<T>::setfirst () const
640 { curr = root; currnr = 1; return (curr?curr->data:NULTP); }
641 
642 template <typename T>
643 inline T* List<T>::setlast () const
644 { /*checklast();*/ curr = last; currnr = count; return (curr?curr->data:NULTP); }
645 
646 template <typename T>
647 inline T* List<T>::setnext () const
648 { if (!curr || !curr->next) return NULTP;
649  else curr = curr->next;
650  currnr++; return curr->data; }
651 
652 template <typename T>
653 inline T* List<T>::setprev () const
654 { if (!curr || !curr->prev) return NULTP;
655  else curr = curr->prev;
656  currnr--; return curr->data; }
657 
658 template <typename T>
659 inline unsigned long List<T>::getlength () const
660 { return count; }
661 
662 template <typename T>
663 inline unsigned long List<T>::size () const
664 { return count; }
665 
666 template <typename T>
667 inline unsigned long List<T>::getcurrnr () const
668 { return currnr; }
669 
670 template <typename T>
671 void List<T>::erase (T* rec) //SLOW!
672 {
673  if (root==NULL)
674  return;
675  ListItem<T> *ptr = root;
676  unsigned int ctr = 0;
677  while (ptr) {
678  ctr++;
679  if (rec == ptr->data) break;
680  ptr = ptr->next;
681  }
682  if (!ptr)
683  return;
684  if (ptr->prev)
685  ptr->prev = ptr->next;
686  else
687  root = ptr->next;
688  if (last == ptr)
689  last = ptr->prev;
690  count--;
691  if (currnr > ctr)
692  currnr--;
693  else if (currnr == ctr) {
694  if (ptr->prev) {
695  curr = ptr->prev;
696  currnr--;
697  } else
698  curr = root;
699  }
700  delete ptr;
701 }
702 
703 template <typename T>
704 unsigned long List<T>::getnr (const T* rec) const //SLOW !
705 {
706  if (root==NULL) return 0;
707  ListItem<T> *ptr = root;
708  long cntr = 0;
709  while (ptr) {
710  cntr++;
711  if (rec == ptr->data) return cntr;
712  ptr = ptr->next;
713  }
714  return 0;
715 }
716 
717 template <typename T>
718 inline unsigned long List<T>::getnr () const
719 { if (curr != NULL) return getnr(curr->data); else return 0; }
720 
721 template <typename T>
722 T* List<T>::getbynr (long ctr) const
723 {
724  if ((unsigned)ctr >= count || root == NULL)
725  return NULTP;
726  ListItem<T> *ptr = root;
727  while (ptr && ctr--)
728  ptr = ptr->next;
729  if (ctr == -1)
730  return ptr->data;
731  else
732  return NULTP;
733 }
734 
735 template <typename T>
736 T* List<T>::setcurrnr (const unsigned long nr) const
737 {
738  curr = root; currnr = 0;
739  while (curr && ++currnr < nr)
740  curr = curr->next;
741  if (curr) return curr->data;
742  else return NULTP;
743 }
744 
745 template <typename T>
746 void List<T>::dumpList () const
747 {
748  ListItem<T>* tmp = root;
749  printf ("Length:%li Curr:%li ", count, currnr);
750  printf ("ROOT=%p CURR=%p LAST=%p\n", root, curr, last);
751  while (tmp) {
752  printf ("Elem:%p Prev:%p Next:%p Data:%p\n", tmp, tmp->prev, tmp->next, tmp->data);
753  tmp = tmp->next;
754  }
755 }
756 
757 #ifdef __WATCOMC__
758 # define EQDOUBLE
759 #else
760 # define EQDOUBLE = double
761 #endif
762 
769 template <typename T, typename S EQDOUBLE>
770 class nsList: public List<T>
771 {
772  protected:
773  using List<T>::root;
774  using List<T>::last;
775  using List<T>::curr;
776  using List<T>::currnr;
777  using List<T>::setlast;
778  bool dir; //sort direction (true = descending)
779  void quick (ListItem<T>*, ListItem<T>*);
780  public:
781  nsList () : List<T> () { dir = false; }
782  void qsort (bool = false);
783  T* sortin_r (T&, bool = false);
784  long move_window (const S & val) const;
785 } ;
786 
787 template <typename T, typename S>
789 {
790  //if (left == right) return;
791  ListItem<T>* le = left; ListItem<T>* ri = right;
792  // Prevent overflow -> double !
793  S test = (S)(((double)le->data->getval()+(double)ri->data->getval())/2);
794  T* tmp;
795  /* Avoid overhead of getnr()
796  ListItem<T>* ptr = le;
797  int zlr = getnr(ptr->data);
798  zlr = (int)(zlr+getnr(ri->data))/2-zlr;
799  for (int i=0; i<zlr; i++) ptr = ptr->next;
800  double test = ptr->data->getval();
801  */
802  /* Debug
803  STD__ cout << "left: " << getnr(le->data) << " " << le->data->getval()
804  << ", right: " << getnr(ri->data) << " " << ri->data->getval()
805  << ", test: " << test << "\n";
806  */
807  int lesri = 1; // 1: le<ri, 0: le=ri; -1: le>ri
808  while (lesri >= 0) {
809  while ((dir?le->data->getval()>test:le->data->getval()<test)) {
810  le = le->next;
811  if (lesri == 0)
812  lesri = -1;
813  else if (le == ri)
814  lesri = 0;
815  }
816  //STD__ cout << "le: " << getnr(le->data) << '\n';
817  while ((dir? ri->data->getval() < test: ri->data->getval() > test)) {
818  ri = ri->prev;
819  if (lesri == 0)
820  lesri = -1;
821  else if (le == ri)
822  lesri = 0;
823  }
824  //STD__ cout << "ri: " << getnr(ri->data) << ", " << lesri << '\n';
825  if (lesri == 1) {
826  tmp = le->data; le->data = ri->data; ri->data = tmp;
827  le = le->next; if (le == ri) lesri = 0;
828  ri = ri->prev;
829  if (lesri == 0) lesri = -1;
830  else if (le == ri) lesri = 0;
831  }
832  else if (lesri == 0) {
833  if (le != right)
834  le = le->next;
835  // FIXME
836  lesri = -1;
837  if (ri != left)
838  ri = ri->prev;
839  }
840  //STD__ cout << "le: " << getnr(le->data) << ", ri: " << getnr(ri->data) << ", " << lesri << '\n';
841  }
842  //STD__ cout << "left " << left << " right " << right << " le " << le << " ri " << ri << '\n';
843  if (left != ri)
844  quick(left,ri);
845  if (le != right)
846  quick(le,right);
847 }
848 
853 template <typename T, typename S>
854 void nsList<T,S>::qsort (bool desc)
855 {
856  dir = desc;
857  if (root == NULL || root == last)
858  return;
859  quick(root,last);
860 }
861 
862 template <class T,class S>
863 T* nsList<T,S>::sortin_r (T& dat, bool frst)
864 {
865  bool sortedin = false;
866  ListItem<T> *ptr, *ptr2;
867  ptr2 = (frst? root: last);
868  bool comp = (dat.getval() < ptr2->data->getval()) ^ dir;
869 
870  if (frst) {
871  ptr2 = root;
872 #ifdef LIST_LANG_C
873  fprintf (stderr, "Not yet implemented !\n");
874 #else
875  STD__ cerr << "Not yet implemented !\n";
876 #endif
877  }
878 
879  else
880  {
881  // ptr2 points to current ListItem, ptr to inserted
882  ptr2 = last;
883  if (!comp) return ptr2->data;
884  //CSTD__ memcpy (ptr2->data, &dat, sizeof(T));
885  *(ptr2->data) = dat;
886  ptr2 = ptr2->prev; // pre-last
887  if (!ptr2) return last->data;
888  ptr2->next = NULL; // make new last
889  ptr = last; last = ptr2;
890  while (ptr2 && !sortedin) {
891  comp = (dat.getval() < ptr2->data->getval()) ^ dir;
892  //sort in
893  if (!comp) {
894  ptr->prev = ptr2; ptr->next = ptr2->next;
895  if (ptr2->next) {
896  ptr2->next->prev = ptr; ptr2->next = ptr;
897  }
898  else
899  last = ptr;
900  sortedin = true;
901  }
902  ptr2 = ptr2->prev;
903  }
904  // sort in at beginning
905  if (!sortedin) {
906  ptr->prev = NULL; ptr->next = root;
907  root->prev = ptr; root = ptr;
908  }
909  //ptr2 = ptr; ptr2nr = getnr(ptr);
910  return (setlast ());
911  }
912 }
913 
914 
915 /* Find where we are in between, rel. to curr. pos. afterwards:
916  * curr->data->getval() <= val <= curr->next->data->getval()
917  * (for an ascending list)
918  * border cases: curr will always be valid, curr->next may not
919  */
920 
921 template <typename T, typename S>
922 long nsList<T, S>::move_window (const S & val) const
923 {
924  long oldnr = currnr;
925  if (!curr) {
926  curr = root; currnr = 1;
927  if (!curr)
928  abort ();
929  }
930  ListItem<T>* next = curr->next;
931  if (!dir) {
932  // ascending
933  /* best case: we're already positioned */
934  if ( (curr == root || curr->data->getval() <= val)
935  && (!next || next->data->getval() >= val))
936  return (currnr - oldnr);
937  /* no: we have to walk :-( */
938  /* go forward */
939  if (next)
940  while (next->next && next->data->getval() < val) {
941  next = next->next; currnr++;
942  }
943  if (curr->next != next) {
944  curr = next->prev;
945  return (currnr - oldnr);
946  }
947  /* go back ... */
948  while (curr->prev && curr->data->getval() > val) {
949  curr = curr->prev; currnr--;
950  }
951  //next = curr->next;
952  return (currnr - oldnr);
953  } else {
954  // descending
955  /* best case: we're already positioned */
956  if ( (curr == root || curr->data->getval() >= val)
957  && (!next || next->data->getval() <= val))
958  return (currnr - oldnr);
959  /* no: we have to walk :-( */
960  /* go forward */
961  if (next)
962  while (next->next && next->data->getval() > val) {
963  next = next->next; currnr++;
964  }
965  if (curr->next != next) {
966  curr = next->prev;
967  return (currnr - oldnr);
968  }
969  /* go back ... */
970  while (curr->prev && curr->data->getval() < val) {
971  curr = curr->prev; currnr--;
972  }
973  //next = curr->next;
974  return (currnr - oldnr);
975  }
976 }
977 
978 #ifdef NAMESPACE_TBCI
980 #endif
981 
982 #endif /* TBCI_LIST_H */
const List< T > * lst
Definition: list.h:68
void erase(T *)
Definition: list.h:671
Definition: list.h:44
unsigned long getnr() const
Definition: list.h:718
#define right
riterator rend() const
Definition: list.h:612
ListIterator(const List< T > &_list, T *dataptr=0)
Definition: list.h:100
bool operator==(const ListIterator< T > &li) const
Definition: list.h:209
ListRIterator(const List< T > &_list, ListItem< T > *li, const unsigned long nr)
Definition: list.h:266
long move_window(const S &val) const
Definition: list.h:922
int dir
Definition: list.h:69
iterator end() const
Definition: list.h:606
ListItem< T > * last
Definition: list.h:301
#define NAMESPACE_TBCI
Definition: basics.h:317
List< T > & alias(const List< T > &)
Definition: list.h:402
T * inscurr()
Definition: list.h:450
void dumpList() const
Definition: list.h:746
void deltree()
Definition: list.h:588
unsigned long size() const
Definition: list.h:663
#define NULTP
Definition: list.h:30
#define NULL
Definition: basics.h:250
T * setprev() const
Definition: list.h:653
T * setfirst() const
Definition: list.h:639
T * getfirst() const
Definition: list.h:617
ListIterator< T > iterator
Definition: list.h:306
ListRIterator< T > & operator=(const ListIterator< T > &)
Definition: list.h:275
ListItem< T > * root
Definition: list.h:300
void checklast()
Definition: list.h:362
ListIterator< T > & operator--()
Definition: list.h:185
unsigned long vers
Definition: list.h:294
T * data
Definition: list.h:47
#define bool
Definition: bool.h:22
Definition: list.h:59
#define STD__
Definition: list.h:33
bool operator!=(const ListIterator< T > &li) const
Definition: list.h:218
T * getbynr(long) const
Definition: list.h:722
ListItem< T > * curr
Definition: list.h:65
ListIterator(const ListIterator< T > &li)
Definition: list.h:76
nsList()
Definition: list.h:781
ListIterator< T > & operator=(const ListIterator< T > &)
Definition: list.h:126
T * getlast() const
Definition: list.h:621
unsigned long count
Definition: list.h:292
unsigned long getlength() const
Definition: list.h:659
T * getprev() const
Definition: list.h:634
riterator rbegin() const
Definition: list.h:609
ListItem()
Definition: list.h:51
long getnr()
Definition: list.h:135
unsigned long vers
Definition: list.h:67
iterator begin() const
Definition: list.h:603
T * getnext() const
Definition: list.h:629
ListItem< T > * detached
Definition: list.h:302
ListItem< T > * app()
Definition: list.h:417
List()
Definition: list.h:310
ListRIterator(const List< T > &_list, T *dataptr)
Definition: list.h:262
bool operator>(const ListIterator< T > &li) const
Definition: list.h:240
ListItem * prev
Definition: list.h:49
bool operator<=(const ListIterator< T > &li) const
Definition: list.h:232
~ListItem()
Definition: list.h:52
T * setcurrnr(const unsigned long) const
Definition: list.h:736
ListItem * next
Definition: list.h:48
~List()
Definition: list.h:329
unsigned long currnr
Definition: list.h:293
ListRIterator(const List< T > &_list, ListItem< T > *li)
Definition: list.h:264
T * sortin_r(T &, bool=false)
Definition: list.h:863
ListItem< T > * curr
Definition: list.h:291
T * getcurr() const
Definition: list.h:625
#define NAMESPACE_END
Definition: basics.h:323
T * operator*() const
Definition: list.h:145
T * setnext() const
Definition: list.h:647
T * append()
Definition: list.h:436
long currnr
Definition: list.h:66
ListRIterator< T > riterator
Definition: list.h:308
A numerically sortable List.
Definition: list.h:770
#define T
Definition: bdmatlib.cc:20
List< T > & operator=(const List< T > &)
Definition: list.h:385
T * setlast() const
Definition: list.h:643
ListIterator< T > & operator++()
Definition: list.h:161
T * setcurr(const T *rec) const
Definition: list.h:354
bool operator<(const ListIterator< T > &li) const
Definition: list.h:224
T * detachcurr()
Definition: list.h:510
unsigned long getcurrnr() const
Note that the numbers are 1-based.
Definition: list.h:667
void quick(ListItem< T > *, ListItem< T > *)
Definition: list.h:788
T * delcurr()
Definition: list.h:475
bool dir
Definition: list.h:778
void qsort(bool=false)
Quicksort is really quick: sorts 1 000 000 records (int) in less than 50 secs on a 486DX4/100 under L...
Definition: list.h:854
bool operator>=(const ListIterator< T > &li) const
Definition: list.h:246