aboutsummaryrefslogtreecommitdiff
path: root/src/OrderedList.H
blob: c5caf1d48dd24d90cfbbd1aa5be5097edd413859 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef __ORDEREDLIST__TMPL_
#define __ORDEREDLIST__TMPL_
/*------------------------------------------------------------
  Typical use of the orderd list type
  
   List<sphere *> SphereList;
   sphere *s;
   SphereList.reset();
   while(s=SphereList.getNext())
       s->visible=1;
------------------------------------------------------------*/
// #include <stdio.h>
// #include <iostream.h>
// #include <string.h>
// #include "NewString.H"

#define FOREACH(item,list) list.reset(); while(item=list.getNext())
#define PFOREACH(item,list) list->reset(); while(item=list->getNext())

template <class T>
class OrderedList
{
  class LLink
  {		
  public:
    T data;		
    LLink *next,*prev;
    LLink(T d,LLink *nxt,LLink *prv=0):
    data(d),next(nxt),prev(prv)
    {
      if(nxt)
	nxt->prev=this;
      if(prv)
	prv->next=this;
    }
    ~LLink()
    {
      if(prev)
	prev->next=next;
      if(next)
	next->prev=prev;	
    }
  };
  LLink *head,*current,*tail;
  int size;
public:
  T nullentry;
  OrderedList():head(0),size(0),current(0),nullentry(0){}
  OrderedList(OrderedList<T> &src):head(0),size(0),current(0),nullentry(0){
    T elem;
    FOREACH(elem,src)
      this->add(elem);
  }
  ~OrderedList(){
    while(head) {
      LLink *tmp=head->next;
      delete head;
      head=tmp;
    }
  }
  void add(T data)
  {
    head=new LLink(data,head);
    size++;
  }
  inline void addToHead(T data){add(data);}
  void addToTail(T data){
    // Whaaaaaa! Totally Bogus Man!!
    // This type aint complete!!!
  }
  void insertAfterCurrent(T data){
    if(!current || !current->next)
      addToTail(data);
    else
      current=new LLink(data,current->next,current);
  }
  void insertBeforeCurrent(T data) {
    if(!current)
      addToTail(data);
    else{
      if(!current->prev)
	add(data);
      else
	new LLink(data,current,current->prev);
    }
  }
  void remove(T data)
  {
    for(LLink *tmp=head;tmp;tmp=tmp->next) {
      if(tmp->data==data){
	if(tmp==head) head=tmp->next;
	if(tmp==current) current=tmp->next;
	delete tmp;
	size--;
      }
    }
  }
  void reset() { current=head; }
  T getNext() { 
    T rval;
    if(!current) return nullentry;
    rval=current->data;
    current=current->next;
    return rval;
  }		
  inline int getSize(){return size;}
  OrderedList &operator=(OrderedList<T> &src){
    if(this==&src) return *this;
    T elem;
    FOREACH(elem,src)
      this->add(elem);
    return *this;
  }
};

#endif // __ORDEREDLIST__TMPL_