vdk 2.4.0
value_sem_list.h
1 /*
2  * ===========================
3  * VDK Visual Development Kit
4  * Version 0.4
5  * October 1998
6  * ===========================
7  *
8  * Copyright (C) 1998, Mario Motta
9  * Developed by Mario Motta <mmotta@guest.net>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24  * 02111-1307, USA.
25  */
26 
46 #ifndef VALUE_SEM_LIST_H
47 #define VALUE_SEM_LIST_H
48 #include <assert.h>
49 #define nihil (VDKValueItem<T>*) 0
50 
51 /*
52  forward
53 */
54 template <class T> class VDKValueList;
55 template <class T> class VDKValueListIterator;
56 
61 template <class T>
63 {
64  friend class VDKValueList<T>;
65  friend class VDKValueListIterator<T>;
66  T data;
67  VDKValueItem *next,*prev;
68  VDKValueItem(const T& data): data(data),next(nihil),prev(nihil)
69  {
70  }
71  ~VDKValueItem()
72  {
73  }
74 };
75 
76 /*
77  class VDKValueList,
78  inherits from Container
79 */
80 template <class T>
82 {
83 
84  protected:
85  VDKValueItem<T> *head,*tail;
86  int count;
87 
88  public:
92  VDKValueList():head(nihil),tail(nihil),count(0) {}
96  VDKValueList(const VDKValueList<T>& l);
104  virtual ~VDKValueList();
108  void add(const T& t);
112  void push( const T& t);
117  int insert( const T& t, bool unique = false);
121  void flush();
125  T& operator[](int n);
130  T* find(T& t);
134  int size() { return count; }
139  bool unlink(int ndx);
143  int at(T& t);
144 
145  protected:
146  friend class VDKValueListIterator<T>;
147  void assign(const VDKValueList<T>& l);
148  VDKValueItem<T>* fetch(int n);
149  void addToTail(VDKValueItem<T>* i);
150  void addToHead(VDKValueItem<T>* i);
151  int insertVDKValueItem(VDKValueItem<T>* i, bool unique);
152 
153 };
178 template <class T>
180 {
181  VDKValueItem<T>* head,*tail,*p;
182  public:
186  VDKValueListIterator():head(nihil),tail(nihil),p(nihil) {}
192  head(l.head),tail(l.tail),p(l.head) {}
200  void operator++() { p = p->next; }
204  void operator++(int) { p = p->next; }
208  void operator--() { p = p->prev; }
212  void operator--(int) { p = p->prev; }
216  void first() { p = head; }
220  void last() { p = tail; }
224  operator int() { return p != nihil; }
228  T& current() { return p->data; }
232  void restart() { p = head; }
233 };
234 
235 
236 /*
237  copy initializer
238 */
239 template <class T>
241 {
242  count = 0;
243  head = tail = nihil;
244  assign(l);
245 }
246 /*
247  assignement
248 */
249 template <class T>
251 {
252  if(this != &l)
253  {
254  flush();
255  assign(l);
256  }
257  return *this;
258 }
259 /*
260  destructor
261 */
262 template <class T>
264 {
265  flush();
266 }
267 /*
268  flushes list
269 */
270 template <class T>
272 {
273  VDKValueItem<T>* p = head;
274  VDKValueItem<T>* p1;
275  while(p)
276  {
277  p1 = p->next;
278  delete p;
279  p = p1;
280  }
281  head = tail = nihil;
282  count = 0;
283 }
284 /*
285  add a T type to list
286 */
287 template <class T>
288 void VDKValueList<T>::add( const T& t)
289 {
290  addToTail(new VDKValueItem<T>(t));
291 }
292 /*
293  pushes a T type into list
294 */
295 template <class T>
296 void VDKValueList<T>::push(const T& t)
297 {
298  addToHead(new VDKValueItem<T>(t));
299 }
300 /*
301  insert in order a T type into list
302 */
303 template <class T>
304 int VDKValueList<T>::insert(const T& t, bool unique)
305 {
306 
307  return insertVDKValueItem(new VDKValueItem<T>(t), unique);
308 }
309 /*
310  ordinal operator
311 */
312 template <class T>
314 {
315  assert(n<count);
316  return fetch(n)->data;
317 }
318 /*
319  find a T type value
320 */
321 template <class T>
323 {
324  VDKValueItem<T>* p = head;
325  for(; p && !(p->data == t); p = p->next);
326  return p ? &(p->data): (T*) 0;
327 }
328 /*
329  */
330 template <class T>
331 int
333  int t = 0;
334  VDKValueItem<T>* p = head;
335  for(; p && !(p->data == x);p = p->next,t++) ;
336  return p ? t : -1;
337 }
338 
339 
340 template <class T>
341 bool
343 {
344  VDKValueItem<T> *x = fetch(ndx);
345  if(!x) return false;
346  if(x->prev != nihil)
347  x->prev->next = x->next;
348  else
349  head = x->next;
350  if(x->next != nihil)
351  x->next->prev = x->prev;
352  else
353  tail = x->prev;
354  count--;
355  delete x;
356  return true;
357 }
358 /*
359  private,
360  copy VDKValueItems from a list
361  into this
362 */
363 template <class T>
365 {
366  for(VDKValueListIterator<T> li(l);li;li++)
367  add(li.current());
368 }
369 /*
370  private,
371  fetches n-th VDKValueItem
372 */
373 template <class T>
375 {
376  int t = 0;
377  VDKValueItem<T>* p ;
378  for(p = head; p && (t<n); t++, p = p->next);
379  return p;
380 }
381 /*
382  private,
383  add an VDKValueItem to tail
384 */
385 template <class T>
387 {
388  if(! head) head = tail = i;
389  else { tail->next = i; i->prev = tail; tail = i; }
390  count++;
391 }
392 /*
393  private,
394  add an VDKValueItem to tail
395 */
396 template <class T>
398 {
399  if(! head) head = tail = i;
400  else { head->prev = i; i->next = head; head = i; }
401  count++;
402 }
403 /*
404  private,
405  add an VDKValueItem in order
406  return inserted list index
407 */
408 template <class T>
410  bool unique)
411 {
412  VDKValueItem<T>* p;
413  int t=0;
414  for(p = head,t=0; p && (p->data < i->data); p = p->next,t++);
415  // avoid key clush
416  if(unique && p && (p->data == i->data))
417  {
418  delete i;
419  return -1;
420  }
421  if(!p)
422  {
423  addToTail(i);
424  return count-1;
425  }
426  else if (p->prev)
427  {
428  p->prev->next = i;
429  i->prev = p->prev;
430  p->prev = i;
431  i->next = p;
432  count++;
433  return t;
434  }
435  else
436  {
437  addToHead(i);
438  return 0;
439  }
440 }
441 #endif
442 
443 
444 
445 
446 
447 
448 
449