GUIDOLib  1.7.7
Guido Engine Internal Documentation
kf_list.h
1 #ifndef KF_LIST_H
2 #define KF_LIST_H
3 
4 /*
5  GUIDO Library
6  Copyright (C) 2002 Holger Hoos, Juergen Kilian, Kai Renz
7  Copyright (C) 2002-2017 Grame
8 
9  This Source Code Form is subject to the terms of the Mozilla Public
10  License, v. 2.0. If a copy of the MPL was not distributed with this
11  file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 
13  Grame Research Laboratory, 11, cours de Verdun Gensoul 69002 Lyon - France
14  research@grame.fr
15 
16 */
17 #include "GuidoDefs.h" // for GuidoPos ...
18 #include <cassert>
19 
20 template <class TYPE>
22 {
23  public:
24  KF_ListNode(TYPE n_data, KF_ListNode<TYPE> *n_prev = 0)
25  : fData( n_data ), fNext( 0 ), fPrev( n_prev ) { }
26 
27  TYPE fData;
30 };
31 
32 template <class TYPE>
33 class KF_List
34 {
35  public:
37 
38  KF_List() : fHead(0), fTail(0), fCount(0) { }
39  virtual ~KF_List() { RemoveAll(); }
40 
41  // - STL-like interface
42  int size() const { return fCount; }
43  bool empty() const { return fCount == 0; }
44  GuidoPos push_back( TYPE data ) { return AddTail( data ); }
45  GuidoPos insert( GuidoPos pos, TYPE data )
46  { return AddElementAt( pos, data ); }
47 
48  TYPE back() const { return GetTail(); } // warning: currently return a copy
49  TYPE front() const { return GetHead(); } // idem
50 
51  // - Original interface
52  virtual void ResetListNoDelete();
53  virtual void RemoveAll();
54  virtual void RemoveElementAt(GuidoPos pos);
55 
56  TYPE RemoveTail()
57  {
58  if (!fTail) return (TYPE) 0;
59 
60  mynode * myprev = fTail->fPrev;
61  TYPE data = fTail->fData;
62  if (fTail == fHead)
63  {
64  delete fTail;
65  fTail = fHead = 0;
66  fCount = 0;
67  }
68  else
69  {
70  delete fTail;
71  fTail = myprev;
72  fTail->fNext = 0;
73  --fCount;
74  }
75  return data;
76  }
77 
78  GuidoPos AddTail(TYPE data) // use push_back instead
79  {
80  mynode * node = new mynode(data,fTail);
81  if (fTail)
82  fTail->fNext = node;
83  else // there is no head therefore no tail
84  fHead = node;
85 
86  fTail = node;
87  ++ fCount;
88  return (GuidoPos) fTail;
89  }
90 
91  GuidoPos AddElementAt(GuidoPos pos,TYPE data);
92  GuidoPos AddElementAfter(GuidoPos pos, TYPE data);
93 
94  int GetCount() const { return fCount; } // replaced by size()
95  int IsEmpty() const { return fCount == 0; } // replaced by empty()
96 
97  GuidoPos SetTailPosition(GuidoPos pos);
98  GuidoPos SetHeadPosition(GuidoPos pos);
99 
100  virtual void Cut(GuidoPos pos,KF_List<TYPE> **pnew);
101 
102  GuidoPos GetHeadPosition(void) const { return (GuidoPos) fHead; }
103  GuidoPos GetTailPosition() const { return (GuidoPos) fTail; }
104 
105  TYPE GetNext(GuidoPos & pos) const
106  {
107  mynode *tmp = (mynode *) pos;
108  pos = (GuidoPos) tmp->fNext;
109  return tmp->fData;
110  }
111 
112  TYPE GetPrev(GuidoPos &pos) const
113  {
114  mynode *tmp = (mynode *) pos;
115  pos = (GuidoPos) tmp->fPrev;
116  return tmp->fData;
117  }
118 
119  TYPE GetAt(GuidoPos pos) const { return ((mynode *)pos)->fData; }
120  void SetAt(GuidoPos pos, TYPE data) { ((mynode *)pos)->fData = data; }
121 
122  TYPE Get(int cnt) const;
123 
124  GuidoPos AddHead(TYPE data)
125  {
126  mynode *node = new mynode(data,0);
127  if (fHead) {
128  fHead->fPrev = node;
129  node->fNext = fHead;
130  }
131  else {
132  // there is no head therefore no tail
133  fTail = node;
134  }
135  fHead = node;
136  ++fCount;
137  return (GuidoPos) fHead;
138  }
139 
140  TYPE RemoveHead()
141  {
142  if (!fHead) return (TYPE) 0;
143  TYPE data = fHead->fData;
144 
145  mynode *tmp = fHead;
146  if (fHead == fTail) {
147  fHead = 0;
148  fTail = 0;
149  }
150  else {
151  fHead = fHead->fNext;
152  fHead->fPrev = 0;
153  }
154  delete tmp;
155  --fCount;
156  return data;
157  }
158 
159  TYPE GetHead() const { return fHead ? fHead->fData : 0; }
160  TYPE GetTail() const { return fTail ? fTail->fData : 0; }
161 
162  // a sort-function, taking as an argument
163  // a function, that compares to elements of
164  // the given type and returns -1 for smaller,
165  // 0 for equal and 1 for bigger.
166  virtual void sort()
167  {
168  // bubble dir einene ...
169  int needssort = 1;
170 
171  while (needssort)
172  {
173  needssort = 0;
174  GuidoPos pos = GetHeadPosition();
175  while (pos)
176  {
177  GuidoPos pos1 = pos;
178  TYPE t1 = GetNext(pos);
179  if (pos)
180  {
181  TYPE t2 = GetAt(pos);
182  if (t1 > t2)
183  {
184  SetAt(pos1,t2);
185  SetAt(pos,t1);
186  needssort = 1;
187  }
188  }
189 
190  }
191  }
192  }
193 
194  protected:
196  mynode * fTail; // at the end will be attached
197  int fCount; // nr of elements
198 
199 };
200 
201 // inserts date BEFORE GuidoPos pos
202 template <class TYPE>
203 GuidoPos KF_List<TYPE>::AddElementAt(GuidoPos pos, TYPE data)
204 {
205  if (((mynode *) pos) == 0 || ((mynode *) pos) == fHead)
206  return AddHead(data);
207 
208  // pos is ptr to KG_ListNode
209  mynode *thisnode = (mynode *) pos;
210  mynode *node = new mynode(data,thisnode->fPrev);
211  node->fNext = thisnode;
212  thisnode->fPrev->fNext = node;
213  thisnode->fPrev = node;
214 
215  fCount++;
216  return (GuidoPos) node;
217 }
218 
219 /* adds the date after the GuidoPos "pos".
220  returns the GuidoPos of the added element" */
221 template <class TYPE>
222 GuidoPos KF_List<TYPE>::AddElementAfter(GuidoPos pos, TYPE data)
223 {
224  if (((mynode *) pos) == 0 || ((mynode *) pos) == fTail)
225  return AddTail(data);
226 
227  // pos is a pointer to a KF_ListNode ...
228  mynode *thisnode = (mynode *) pos;
229  mynode *node = new mynode(data,thisnode);
230  node->fNext = thisnode->fNext;
231  node->fNext->fPrev = node;
232  thisnode->fNext = node;
233  fCount++;
234  return (GuidoPos) node;
235 }
236 
237 template <class TYPE>
239 {
240  mynode *cur = fHead;
241  while (cur)
242  {
243  mynode * tmp = cur->fNext;
244  delete cur;
245  cur = tmp;
246  }
247  fHead = 0;
248  fTail = 0;
249  fCount = 0;
250 }
251 
252 template <class TYPE>
254 {
255  fHead = 0;
256  fTail = 0;
257  fCount = 0;
258 }
259 
260 template <class TYPE>
262 {
263  if (!pos) return;
264  mynode *cur = (mynode *) pos;
265 
266  if (cur->fPrev)
267  cur->fPrev->fNext = cur->fNext;
268 
269  if (cur->fNext)
270 
271  cur->fNext->fPrev = cur->fPrev;
272 
273  if (cur == fHead)
274  fHead = cur->fNext;
275  if (cur == fTail)
276  fTail = cur->fPrev;
277  delete cur;
278  fCount--;
279 }
280 
281 
282 template <class TYPE>
283 GuidoPos KF_List<TYPE>::SetTailPosition(GuidoPos pos)
284 {
285  // we don't care, what happens with the
286  // rest of the list ... it is not
287  // deleted by this function!
288 
289  fTail = (mynode *) pos;
290  if (fTail)
291  fTail->fNext = 0;
292 
293  // then we have to recount!
294  fCount = 0;
295  mynode *cur = fHead;
296  while (cur)
297  {
298  fCount++;
299  if (!cur->fNext)
300  {
301  // this ensure, that the given tail
302  // was somewhere in the list already
303  assert(cur == fTail);
304  }
305  cur = cur->fNext;
306  }
307 
308  return (GuidoPos) fTail;
309 }
310 
311 template <class TYPE>
312 TYPE KF_List<TYPE>::Get(int cnt) const
313 {
314  int tmpcnt = 1;
315  GuidoPos pos = GetHeadPosition();
316  while (pos)
317  {
318  TYPE mydata = GetNext(pos);
319  if (tmpcnt == cnt)
320  return mydata;
321  tmpcnt++;
322  }
323  return (TYPE) 0;
324 }
325 
326 template <class TYPE>
327 GuidoPos KF_List<TYPE>::SetHeadPosition(GuidoPos pos)
328 {
329 
330  assert(!fHead);
331  assert(!fTail);
332 
333  fHead = (mynode *) pos;
334  if (fHead)
335  fHead->fPrev = 0;
336 
337  // then we have to recount!
338  fCount = 0;
339  mynode *cur = fHead;
340  while (cur)
341  {
342  fCount++;
343  if (!cur->fNext)
344  fTail = cur;
345  cur = cur->fNext;
346  }
347 
348  return (GuidoPos) fHead;
349 }
350 
351 
352 template <class TYPE>
353 void KF_List<TYPE>::Cut(GuidoPos pos,KF_List<TYPE> **pnew)
354 {
355  // first, we create the new list:
356  *pnew = new KF_List<TYPE>;
357 
358  // this remembers the head-GuidoPos for the new-list
359  mynode *node = (mynode *) pos;
360 
361  if (node)
362  {
363  node = node->fNext;
364  // then, we set the tail-GuidoPos of the
365  // current list
366  SetTailPosition(pos);
367 
368  // and the head-GuidoPos (and tail-pos)
369  // of the new-list
370 
371  (*pnew)->SetHeadPosition((GuidoPos) node);
372 
373  }
374  else
375  {
376  // then, we try to cut at the
377  // very beginning!
378  (*pnew)->SetHeadPosition((GuidoPos) fHead);
379 
380  fHead = 0;
381  fTail = 0;
382  fCount = 0;
383  }
384 }
385 
386 #endif
KF_List::AddTail
GuidoPos AddTail(TYPE data)
Definition: kf_list.h:78
KF_ListNode::fData
TYPE fData
Definition: kf_list.h:27
KF_List::AddHead
GuidoPos AddHead(TYPE data)
Definition: kf_list.h:124
KF_List::GetHead
TYPE GetHead() const
Definition: kf_list.h:159
KF_List::back
TYPE back() const
Definition: kf_list.h:48
KF_List::GetCount
int GetCount() const
Definition: kf_list.h:94
KF_List::GetTailPosition
GuidoPos GetTailPosition() const
Definition: kf_list.h:103
KF_List::sort
virtual void sort()
Definition: kf_list.h:166
KF_List::GetTail
TYPE GetTail() const
Definition: kf_list.h:160
KF_List::GetNext
TYPE GetNext(GuidoPos &pos) const
Definition: kf_list.h:105
KF_ListNode::KF_ListNode
KF_ListNode(TYPE n_data, KF_ListNode< TYPE > *n_prev=0)
Definition: kf_list.h:24
KF_List::SetAt
void SetAt(GuidoPos pos, TYPE data)
Definition: kf_list.h:120
KF_List::fCount
int fCount
Definition: kf_list.h:197
KF_List::Get
TYPE Get(int cnt) const
Definition: kf_list.h:312
KF_ListNode::fPrev
KF_ListNode * fPrev
Definition: kf_list.h:29
KF_List::GetAt
TYPE GetAt(GuidoPos pos) const
Definition: kf_list.h:119
KF_ListNode::fNext
KF_ListNode * fNext
Definition: kf_list.h:28
KF_List::insert
GuidoPos insert(GuidoPos pos, TYPE data)
Definition: kf_list.h:45
KF_List::Cut
virtual void Cut(GuidoPos pos, KF_List< TYPE > **pnew)
Definition: kf_list.h:353
KF_List::size
int size() const
Definition: kf_list.h:42
KF_List::mynode
KF_ListNode< TYPE > mynode
Definition: kf_list.h:36
KF_List::GetPrev
TYPE GetPrev(GuidoPos &pos) const
Definition: kf_list.h:112
KF_List::~KF_List
virtual ~KF_List()
Definition: kf_list.h:39
KF_List::KF_List
KF_List()
Definition: kf_list.h:38
KF_List::AddElementAfter
GuidoPos AddElementAfter(GuidoPos pos, TYPE data)
Definition: kf_list.h:222
KF_List::SetHeadPosition
GuidoPos SetHeadPosition(GuidoPos pos)
Definition: kf_list.h:327
KF_List::fTail
mynode * fTail
Definition: kf_list.h:196
KF_List::push_back
GuidoPos push_back(TYPE data)
Definition: kf_list.h:44
KF_List::RemoveHead
TYPE RemoveHead()
Definition: kf_list.h:140
KF_List::AddElementAt
GuidoPos AddElementAt(GuidoPos pos, TYPE data)
Definition: kf_list.h:203
KF_List::IsEmpty
int IsEmpty() const
Definition: kf_list.h:95
KF_List::fHead
mynode * fHead
Definition: kf_list.h:195
KF_List::empty
bool empty() const
Definition: kf_list.h:43
KF_List::RemoveAll
virtual void RemoveAll()
Definition: kf_list.h:238
KF_List::ResetListNoDelete
virtual void ResetListNoDelete()
Definition: kf_list.h:253
KF_List::RemoveTail
TYPE RemoveTail()
Definition: kf_list.h:56
KF_List::GetHeadPosition
GuidoPos GetHeadPosition(void) const
Definition: kf_list.h:102
KF_List::RemoveElementAt
virtual void RemoveElementAt(GuidoPos pos)
Definition: kf_list.h:261
KF_ListNode
Definition: kf_list.h:21
KF_List
Definition: GRBreakMatrix.h:24
KF_List::front
TYPE front() const
Definition: kf_list.h:49
KF_List::SetTailPosition
GuidoPos SetTailPosition(GuidoPos pos)
Definition: kf_list.h:283

Guido Project Copyright © 2019 Grame-CNCM