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
43template <typename T>
44class ListItem {
45 private:
46 public:
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
59template <typename T> class List;
60/* Iterators */
61template <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
99template <typename T>
100ListIterator<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
109template <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
119template <typename T>
121 const long nr)
122 : curr (li), currnr (nr), vers (_list.vers), lst (&_list), dir (1)
123{}
124
125template <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
134template <typename T>
136{
137 if (vers != lst->vers) {
138 currnr = lst->getnr (curr->data);
139 vers = lst->vers;
140 }
141 return currnr;
142}
143
144template <typename T>
146{
147 return curr->data;
148}
149
150template <typename T>
152{
153 if (curr)
154 return true;
155 else
156 return false;
157}
158
159
160template <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
184template <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
208template <typename T>
210{
211 if (lst == li.lst /*&& dir == li.dir*/ && currnr == li.currnr)
212 return true;
213 else
214 return false;
215}
216
217template <typename T>
219{
220 return !(*this == li);
221}
222
223template <typename T>
225{
226 if (lst != li.lst /*|| dir != li.dir*/)
227 abort ();
228 return (dir * currnr < li.dir * li.currnr);
229}
230
231template <typename T>
233{
234 if (lst != li.lst /*|| dir != li.dir*/)
235 abort ();
236 return (dir * currnr <= li.dir * li.currnr);
237}
238
239template <typename T>
241{
242 return !(*this <= li);
243}
244
245template <typename T>
247{
248 return !(*this < li);
249}
250
251
252template <typename T>
254{
255 protected:
256 using ListIterator<T>::dir;
257 using ListIterator<T>::curr;
258 using ListIterator<T>::currnr;
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; }
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
274template <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
288template <typename T>
289class List {
290 protected:
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
361template <typename T>
362inline 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
370template <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
384template <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
401template <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
416template <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
435template <typename T>
437{
438 return app()->data;
439}
440
441template <typename T>
442inline T* List<T>::append (T* data)
443{
444 T *tmp = this->append ();
445 *tmp = *data; return tmp;
446}
447
448
449template <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
466template <typename T>
467inline T* List<T>::inscurr (T* elem)
468{
469 T* ptr = inscurr ();
470 *ptr = *elem;
471 return ptr;
472}
473
474template <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
509template <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
557template <typename T>
558void 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
587template <typename T>
588inline 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
602template <typename T>
603inline typename List<T>::iterator List<T>::begin () const
604{ return ListIterator<T> (*this, root, (long)1); }
605template <typename T>
606inline typename List<T>::iterator List<T>::end () const
607{ return ListIterator<T> (*this, 0, (long)count+1); }
608template <typename T>
609inline typename List<T>::riterator List<T>::rbegin () const
610{ return ListRIterator<T> (*this, last, (long)count); }
611template <typename T>
612inline typename List<T>::riterator List<T>::rend () const
613{ return ListRIterator<T> (*this, 0, (long)0); }
614
615
616template <typename T>
617inline T* List<T>::getfirst () const
618{ return (root?root->data:NULTP); }
619
620template <typename T>
621inline T* List<T>::getlast () const
622{ /*checklast();*/ return (last?last->data:NULTP); }
623
624template <typename T>
625inline T* List<T>::getcurr () const
626{ return (curr?curr->data:NULTP); }
627
628template <typename T>
629inline T* List<T>::getnext () const
630{ if (!curr || !curr->next) return NULTP;
631 else return curr->next->data; }
632
633template <typename T>
634inline T* List<T>::getprev () const
635{ if (!curr || !curr->prev) return NULTP;
636 else return curr->prev->data; }
637
638template <typename T>
639inline T* List<T>::setfirst () const
640{ curr = root; currnr = 1; return (curr?curr->data:NULTP); }
641
642template <typename T>
643inline T* List<T>::setlast () const
644{ /*checklast();*/ curr = last; currnr = count; return (curr?curr->data:NULTP); }
645
646template <typename T>
647inline T* List<T>::setnext () const
648{ if (!curr || !curr->next) return NULTP;
649 else curr = curr->next;
650 currnr++; return curr->data; }
651
652template <typename T>
653inline T* List<T>::setprev () const
654{ if (!curr || !curr->prev) return NULTP;
655 else curr = curr->prev;
656 currnr--; return curr->data; }
657
658template <typename T>
659inline unsigned long List<T>::getlength () const
660{ return count; }
661
662template <typename T>
663inline unsigned long List<T>::size () const
664{ return count; }
665
666template <typename T>
667inline unsigned long List<T>::getcurrnr () const
668{ return currnr; }
669
670template <typename T>
671void 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
703template <typename T>
704unsigned 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
717template <typename T>
718inline unsigned long List<T>::getnr () const
719{ if (curr != NULL) return getnr(curr->data); else return 0; }
720
721template <typename T>
722T* 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
735template <typename T>
736T* 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
745template <typename T>
746void 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
768
769template <typename T, typename S EQDOUBLE>
770class 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
787template <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
853template <typename T, typename S>
854void nsList<T,S>::qsort (bool desc)
855{
856 dir = desc;
857 if (root == NULL || root == last)
858 return;
859 quick(root,last);
860}
861
862template <class T,class S>
863T* 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
921template <typename T, typename S>
922long 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 */
#define NULL
Definition basics.h:250
#define NAMESPACE_END
Definition basics.h:323
#define NAMESPACE_TBCI
Definition basics.h:317
#define T
Definition bdmatlib.cc:20
#define bool
Definition bool.h:22
Definition list.h:289
T * setnext() const
Definition list.h:647
T * getprev() const
Definition list.h:634
void deltree(T *)
Deletes List from item to end.
Definition list.h:558
T * inscurr()
Definition list.h:450
~List()
Definition list.h:329
unsigned long size() const
Definition list.h:663
T * setfirst() const
Definition list.h:639
riterator rend() const
Definition list.h:612
iterator end() const
Definition list.h:606
T * setcurr(const T *rec) const
Definition list.h:354
void dumpList() const
Definition list.h:746
ListIterator< T > iterator
Definition list.h:306
T * setprev() const
Definition list.h:653
T * getlast() const
Definition list.h:621
List()
Definition list.h:310
unsigned long currnr
Definition list.h:293
void deltree()
Definition list.h:588
T * append()
Definition list.h:436
List< T > & operator=(const List< T > &)
Definition list.h:385
iterator begin() const
Definition list.h:603
ListItem< T > * detached
Definition list.h:302
List< T > & alias(const List< T > &)
Definition list.h:402
T * setlast() const
Definition list.h:643
ListItem< T > * app()
Definition list.h:417
unsigned long getcurrnr() const
Note that the numbers are 1-based.
Definition list.h:667
T * delcurr()
Definition list.h:475
ListItem< T > * curr
Definition list.h:291
unsigned long vers
Definition list.h:294
T * getbynr(long) const
Definition list.h:722
T * setcurrnr(const unsigned long) const
Definition list.h:736
unsigned long getnr(const T *) const
Definition list.h:704
T * getcurr() const
Definition list.h:625
T * detachcurr()
Definition list.h:510
ListItem< T > * last
Definition list.h:301
unsigned long getnr() const
Definition list.h:718
ListItem< T > * root
Definition list.h:300
void checklast()
Definition list.h:362
void erase(T *)
Definition list.h:671
riterator rbegin() const
Definition list.h:609
unsigned long count
Definition list.h:292
T * getnext() const
Definition list.h:629
T * getfirst() const
Definition list.h:617
unsigned long getlength() const
Definition list.h:659
ListRIterator< T > riterator
Definition list.h:308
ListItem()
Definition list.h:51
ListItem * next
Definition list.h:48
~ListItem()
Definition list.h:52
ListItem * prev
Definition list.h:49
T * data
Definition list.h:47
bool operator<(const ListIterator< T > &li) const
Definition list.h:224
ListItem< T > * curr
Definition list.h:65
bool operator<=(const ListIterator< T > &li) const
Definition list.h:232
ListIterator< T > & operator--()
Definition list.h:185
ListIterator< T > & operator++()
Definition list.h:161
long currnr
Definition list.h:66
bool operator!=(const ListIterator< T > &li) const
Definition list.h:218
const List< T > * lst
Definition list.h:68
T * operator*() const
Definition list.h:145
int dir
Definition list.h:69
ListIterator(const ListIterator< T > &li)
Definition list.h:76
bool operator==(const ListIterator< T > &li) const
Definition list.h:209
ListIterator< T > & operator=(const ListIterator< T > &)
Definition list.h:126
bool operator>=(const ListIterator< T > &li) const
Definition list.h:246
unsigned long vers
Definition list.h:67
long getnr()
Definition list.h:135
ListIterator(const List< T > &_list, T *dataptr=0)
Definition list.h:100
bool operator>(const ListIterator< T > &li) const
Definition list.h:240
ListRIterator(const List< T > &_list, T *dataptr)
Definition list.h:262
ListRIterator(const List< T > &_list, ListItem< T > *li)
Definition list.h:264
ListRIterator(const List< T > &_list, ListItem< T > *li, const unsigned long nr)
Definition list.h:266
ListRIterator< T > & operator=(const ListIterator< T > &)
Definition list.h:275
nsList()
Definition list.h:781
void quick(ListItem< T > *, ListItem< T > *)
Definition list.h:788
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 dir
Definition list.h:778
T * sortin_r(T &, bool=false)
Definition list.h:863
long move_window(const S &val) const
Definition list.h:922
#define STD__
Definition list.h:33
#define NULTP
Definition list.h:30
#define right