gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
LinkList.H
Go to the documentation of this file.
1 /* Copyright 1998-2018 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 
24 //#define LINKLIST_DEBUG
25 
32 template <class TYPE>
33 class Lug {
34 
35 protected:
36 
37 public:
38 
41 
42  TYPE ptr; // The element to point to
43 
45  Lug(void) {
46  next = this;
47  prev = this;
48 #ifdef LINKLIST_DEBUG
49  std::cout <<"LinkList: Adding first "<<this<<" with previous "<< prev << " next " << next <<std::endl;
50 #endif
51  }
53  Lug(Lug<TYPE> * oldOne) {
54  next = (*oldOne).getNext();
55  prev = oldOne;
56 #ifdef LINKLIST_DEBUG
57  std::cout <<"LinkList: Adding "<<this<<" with previous "<< prev << " next " << next <<std::endl;
58 #endif
59  (*oldOne).getNext()->prev = this;
60  (*oldOne).next = this;
61  }
62 
63  // ~Lug(void){}
64 
66  Lug *
67  getNext(void) {
68 #ifdef LINKLIST_DEBUG
69  std::cout <<"LinkList: getNext = "<< next <<std::endl;
70 #endif
71  return next;
72  }
73 
75  Lug *
76  getPrev(void) {
77 #ifdef LINKLIST_DEBUG
78  std::cout <<"LinkList: getPrev = "<< prev <<std::endl;
79 #endif
80  return prev;
81  }
82 };
83 
84 template <class TYPE>
85 class LinkList {
86 
89  long count;
90 public:
91  // Direction ...
92  typedef enum {FWD, REV} direction;
93  direction dir;
94 
98  LinkList(void) {
99  lug = (Lug<TYPE>*)NULL;
100  dir = FWD;
101  count =0;
102  }
103 
105  virtual ~LinkList(void) {
106 #ifdef LINKLIST_DEBUG
107  std::cout <<"LinkList:~LinkList removing "<<std::endl;
108 #endif
109 
110  while (lug != (Lug<TYPE>*)NULL)
111  remove();
112  }
113 
114 
119  void add(TYPE newElement) { // Add the ptr
120 #ifdef LINKLIST_DEBUG
121  std::cout <<"LinkList:add "<< newElement <<std::endl;
122 #endif
123  if (lug == (Lug<TYPE>*)NULL) { // create the first ...
124  lug = new Lug<TYPE>;
125  startLug = lug;
126  } else // Add infront of the current lug
127  lug = new Lug<TYPE>(lug);
128  lug->ptr = newElement;
129  count++;
130  }
131 
137  TYPE change(TYPE changeElement) { // exchange ptr's
138 #ifdef LINKLIST_DEBUG
139  std::cout <<"LinkList:change "<< changeElement <<std::endl;
140 #endif
141  if (lug != (Lug<TYPE>*)NULL) {
142  TYPE tempPtr = lug->ptr;
143  lug->ptr = changeElement;
144  return tempPtr;
145  } else
146  return (TYPE)NULL;
147  }
148 
153  TYPE remove(void) { // Remove the current lug and return the ptr
154  if (lug != (Lug<TYPE>*)NULL) {
155  if (lug == startLug)
156  startLug = lug->getNext();
157  Lug<TYPE>* tempLug = lug;
158  TYPE tempPtr = lug->ptr;
159 
160  if (lug->getNext() == lug) { // Only one lug exists !
161  lug = (Lug<TYPE>*)NULL;
162  } else {
163  lug->getPrev()->next = lug->getNext();
164  lug->getNext()->prev = lug->getPrev();
165  if (dir == FWD)
166  lug = lug->getNext();
167  else
168  lug = lug->getPrev();
169  }
170  count--;
171  delete tempLug;
172  return tempPtr;
173  } else {
174  return (TYPE)0;//NULL;
175  }
176  }
177 
178  /* BAD IDEA ! - what if the lug->ptr is not a ptr !
179  void delAll(void){
180  while (getCount())
181  del();
182  }
183 
184  void del(void){ // Delete the current lug
185  if (lug != (Lug<TYPE>*)NULL){
186  if (lug == startLug)
187  startLug = lug->getNext();
188  Lug<TYPE>* tempLug = lug;
189  TYPE tempPtr = lug->ptr;
190 
191  if (lug->getNext() == lug){ // Only one lug exists !
192  lug = (Lug<TYPE>*)NULL;
193  } else {
194  lug->getPrev()->next = lug->getNext();
195  lug->getNext()->prev = lug->getPrev();
196  if (dir == FWD)
197  lug = lug->getNext();
198  else
199  lug = lug->getPrev();
200  }
201  count--;
202  delete tempLug;
203  delete tempPtr;
204  // return tempPtr;
205  }
206  }
207  */
208 
212  TYPE current(void) { // Return the current ptr
213 #ifdef LINKLIST_DEBUG
214  std::cout <<"LinkList:current " <<std::endl;
215 #endif
216  if (lug != (Lug<TYPE>*)NULL)
217  return lug->ptr;
218  else
219  return (TYPE)NULL;
220  }
221 
226  TYPE next(void) { // return the next ptr
227 #ifdef LINKLIST_DEBUG
228  std::cout <<"LinkList:next "<<std::endl;
229 #endif
230  if (lug != (Lug<TYPE>*)NULL) {
231  if (dir == FWD)
232  lug = lug->getNext();
233  else
234  lug = lug->getPrev();
235  return lug->ptr;
236  } else
237  return (TYPE)0;//NULL;
238  }
239 
244  TYPE prev(void) { // return the previous ptr
245  if (lug != (Lug<TYPE>*)NULL) {
246  if (dir == FWD)
247  lug = lug->getPrev();
248  else
249  lug = lug->getNext();
250  return lug->ptr;
251  } else
252  return (TYPE)0;//NULL;
253  }
254 
259  TYPE grab(int i) { // return the i'th lug in the chain
260 #ifdef LINKLIST_DEBUG
261  std::cout <<"LinkList:grab "<< i <<std::endl;
262 #endif
263  if (i<=0) {
264  std::cerr<<"LinkList: grab: index is less then or equal to zero"<<std::endl;
265  return (TYPE)0;// NULL;
266  } else if (i>count) {
267  std::cerr<<"LinkList: grab: index exceeds count"<<std::endl;
268  return (TYPE)0;// NULL;
269  } else {
270  lug = startLug;
271 
272  while (--i)
273  lug = lug->getNext();
274  return lug->ptr;
275  }
276  }
277 
278  int getCount(void) {
279 #ifdef LINKLIST_DEBUG
280  std::cout <<"LinkList:getCount "<< count <<std::endl;
281 #endif
282  return count;
283  }
284 
290  friend std::ostream& operator <<(std::ostream& o, LinkList* l) {
291  if (l->getCount()==0) return o;
292  l->grab(1);
293  l->prev();
294  for (int j=0; j<l->getCount(); j++)
295  o<<l->next()<<' ';
296  o<<std::endl;
297  return o;
298  }
304  friend std::ostream& operator <<(std::ostream& o, LinkList& l) {
305  if (l.getCount()==0) return o;
306  l.grab(1);
307  l.prev();
308  for (int j=0; j<l.getCount(); j++)
309  o<<l.next()<<' ';
310  o<<std::endl;
311  return o;
312  }
313 
317  TYPE getEnd(){
318  grab(1); // get the head.
319  return prev(); // get the end element
320  }
321 };
322 #endif // LINKLIST_H
Lug * getPrev(void)
Return a pointer to the previous element.
Definition: LinkList.H:76
Lug * getNext(void)
Return a pointer to the next element.
Definition: LinkList.H:67
Lug(Lug< TYPE > *oldOne)
Links to previous element and next element.
Definition: LinkList.H:53
TYPE ptr
Definition: LinkList.H:42
Lug< TYPE > * next
Links to the next and prev elements in the list.
Definition: LinkList.H:40
Lug(void)
This is for the first element - links to itself.
Definition: LinkList.H:45
Defines a lug in a linked list The concept is simple, this Lug points to a next or previous Lug...
Definition: LinkList.H:33
std::ostream & operator<<(std::ostream &stream, const BitStream &bitStream)
Definition: BitStream.C:204
Lug< TYPE > * prev
Definition: LinkList.H:40
gtkIOStream: /tmp/gtkiostream/include/mffm/LinkList.H Source File
GTK+ IOStream  Beta