GTK+ IOStream  Beta
<< GTK+ >> add C++ IOStream operators to GTK+. Now with extra abilities ... like network serialisation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LinkList.H
Go to the documentation of this file.
1 /* Copyright 1998 - 2012 Matt Flax <flatmax@flatmax.org>
2  This file is now part of MFFM VectorBass.
3 
4  MFFM VectorBass is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  MFFM VectorBass is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with MFFM VectorBass
16  */
17 
18 #ifndef LINKLIST_H
19 #define LINKLIST_H
20 
21 #include <sys/types.h>
22 #include <iostream>
23 //#include <iomanip>
24 
25 //#define LINKLIST_DEBUG
26 
33 template <class TYPE>
34 class Lug {
35 
36 protected:
37 
38 public:
39 
42 
43  TYPE ptr; // The element to point to
44 
46  Lug(void) {
47  next = this;
48  prev = this;
49 #ifdef LINKLIST_DEBUG
50  std::cout <<"LinkList: Adding first "<<this<<" with previous "<< prev << " next " << next <<std::endl;
51 #endif
52  }
54  Lug(Lug<TYPE> * oldOne) {
55  next = (*oldOne).getNext();
56  prev = oldOne;
57 #ifdef LINKLIST_DEBUG
58  std::cout <<"LinkList: Adding "<<this<<" with previous "<< prev << " next " << next <<std::endl;
59 #endif
60  (*oldOne).getNext()->prev = this;
61  (*oldOne).next = this;
62  }
63 
64  // ~Lug(void){}
65 
67  Lug *
68  getNext(void) {
69  return next;
70  }
71 
73  Lug *
74  getPrev(void) {
75  return prev;
76  }
77 };
78 
79 template <class TYPE>
80 class LinkList {
81 
84  long count;
85 public:
86  // Direction ...
87  typedef enum {FWD, REV} direction;
89 
93  LinkList(void) {
94  lug = (Lug<TYPE>*)NULL;
95  dir = FWD;
96  count =0;
97  }
98 
100  virtual ~LinkList(void) {
101  while (lug != (Lug<TYPE>*)NULL)
102  remove();
103  }
104 
105 
110  void add(TYPE newElement) { // Add the ptr
111  if (lug == (Lug<TYPE>*)NULL) { // create the first ...
112  lug = new Lug<TYPE>;
113  startLug = lug;
114  } else // Add infront of the current lug
115  lug = new Lug<TYPE>(lug);
116  lug->ptr = newElement;
117  count++;
118  }
119 
125  TYPE change(TYPE changeElement) { // exchange ptr's
126  if (lug != (Lug<TYPE>*)NULL) {
127  TYPE tempPtr = lug->ptr;
128  lug->ptr = changeElement;
129  return tempPtr;
130  } else
131  return (TYPE)NULL;
132  }
133 
138  TYPE remove(void) { // Remove the current lug and return the ptr
139  if (lug != (Lug<TYPE>*)NULL) {
140  if (lug == startLug)
141  startLug = lug->getNext();
142  Lug<TYPE>* tempLug = lug;
143  TYPE tempPtr = lug->ptr;
144 
145  if (lug->getNext() == lug) { // Only one lug exists !
146  lug = (Lug<TYPE>*)NULL;
147  } else {
148  lug->getPrev()->next = lug->getNext();
149  lug->getNext()->prev = lug->getPrev();
150  if (dir == FWD)
151  lug = lug->getNext();
152  else
153  lug = lug->getPrev();
154  }
155  count--;
156  delete tempLug;
157  return tempPtr;
158  } else {
159  return (TYPE)0;//NULL;
160  }
161  }
162 
163  /* BAD IDEA ! - what if the lug->ptr is not a ptr !
164  void delAll(void){
165  while (getCount())
166  del();
167  }
168 
169  void del(void){ // Delete the current lug
170  if (lug != (Lug<TYPE>*)NULL){
171  if (lug == startLug)
172  startLug = lug->getNext();
173  Lug<TYPE>* tempLug = lug;
174  TYPE tempPtr = lug->ptr;
175 
176  if (lug->getNext() == lug){ // Only one lug exists !
177  lug = (Lug<TYPE>*)NULL;
178  } else {
179  lug->getPrev()->next = lug->getNext();
180  lug->getNext()->prev = lug->getPrev();
181  if (dir == FWD)
182  lug = lug->getNext();
183  else
184  lug = lug->getPrev();
185  }
186  count--;
187  delete tempLug;
188  delete tempPtr;
189  // return tempPtr;
190  }
191  }
192  */
193 
197  TYPE current(void) { // Return the current ptr
198  if (lug != (Lug<TYPE>*)NULL)
199  return lug->ptr;
200  else
201  return (TYPE)NULL;
202  }
203 
208  TYPE next(void) { // return the next ptr
209  if (lug != (Lug<TYPE>*)NULL) {
210  if (dir == FWD)
211  lug = lug->getNext();
212  else
213  lug = lug->getPrev();
214  return lug->ptr;
215  } else
216  return (TYPE)0;//NULL;
217  }
218 
223  TYPE prev(void) { // return the previous ptr
224  if (lug != (Lug<TYPE>*)NULL) {
225  if (dir == FWD)
226  lug = lug->getPrev();
227  else
228  lug = lug->getNext();
229  return lug->ptr;
230  } else
231  return (TYPE)0;//NULL;
232  }
233 
238  TYPE grab(int i) { // return the i'th lug in the chain
239  if (i<=0) {
240  std::cerr<<"LinkList: grab: index is less then or equal to zero"<<std::endl;
241  return (TYPE)0;// NULL;
242  } else if (i>count) {
243  std::cerr<<"LinkList: grab: index exceeds count"<<std::endl;
244  return (TYPE)0;// NULL;
245  } else {
246  lug = startLug;
247 
248  while (--i)
249  lug = lug->getNext();
250  return lug->ptr;
251  }
252  }
253 
254  int getCount(void) {
255  return count;
256  }
257 
263  friend std::ostream& operator <<(std::ostream& o, LinkList* l) {
264  if (l->getCount()==0) return o;
265  l->grab(1);
266  l->prev();
267  for (int j=0; j<l->getCount(); j++)
268  o<<l->next()<<' ';
269  o<<std::endl;
270  return o;
271  }
277  friend std::ostream& operator <<(std::ostream& o, LinkList& l) {
278  if (l.getCount()==0) return o;
279  l.grab(1);
280  l.prev();
281  for (int j=0; j<l.getCount(); j++)
282  o<<l.next()<<' ';
283  o<<std::endl;
284  return o;
285  }
286 };
287 #endif // LINKLIST_H