Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
symlist.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file symlist.h
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // symlist.h
5 //
6 //==========================================================================
7 // $Id: symlist.h,v 1.17 2002/12/20 08:26:08 chris Exp $
8 
9 #ifndef SYMLIST_H
10 #define SYMLIST_H
11 
12 #include <GTL/GTL.h>
13 
14 #include <cassert>
15 
17 
21 template <class T>
22 struct symnode
23 {
28  {
29  }
30 
34  symnode(const T& n) : data(n)
35  {
36  }
37 
41  symnode* adj[2];
42 
47 };
48 
52 template <class T, class Ref>
54 {
59 
63  typedef symnode<T>* linktype;
64 
69  {
70  }
71 
75  symlist_iterator(const self& it) : act(it.act), dir(it.dir)
76  {
77  }
78 
82  symlist_iterator(linktype _act, int _dir) : act(_act), dir(_dir)
83  {
84  }
85 
90  act(_act),
91  dir (where_not (_act, _prev))
92  {
93  }
94 
98  self& operator=(const self& it)
99  {
100  act = it.act;
101  dir = it.dir;
102  return *this;
103  }
104 
108  bool operator==(const self& it) const
109  {
110  return act == it.act;
111  }
112 
116  bool operator!=(const self& it) const
117  {
118  return act != it.act;
119  }
120 
125  {
126  return act->data;
127  }
128 
132  self& operator++();
133 
137  self& operator--();
138 
142  static int where(linktype _act, linktype _prev)
143  {
144  return _prev == _act->adj[0] ? 0 : 1;
145  }
146 
150  static int where_not(linktype _act, linktype _prev)
151  {
152  return _prev == _act->adj[1] ? 0 : 1;
153  }
154 
158  void reverse()
159  {
160  dir = 1 - dir;
161  }
162 
167  {
168  return act->adj[dir];
169  }
170 
175  {
176  return act->adj[1 - dir];
177  }
178 
183 
187  int dir;
188 };
189 
208 template <class T>
209 class symlist
210 {
211 public:
216 
221 
226  {
227  link = new symnode<T>;
228  link->adj[0] = link->adj[1] = link;
229  }
230 
236  symlist(const symlist<T>& li);
237 
247  symlist<T>& operator=(const symlist<T>& li);
248 
252  ~symlist();
253 
261  bool empty() const
262  {
263  return link->adj[0] == link && link->adj[1] == link;
264  }
265 
273  T& front()
274  {
275  return link->adj[0]->data;
276  }
277 
285  T& back()
286  {
287  return link->adj[1]->data;
288  }
289 
296  {
297  return ++end();
298  }
299 
306  {
307  return iterator(link, 0);
308  }
309 
316  {
317  return ++end();
318  }
319 
326  {
327  return const_iterator (link, 0);
328  }
329 
336  {
337  return ++rend();
338  }
339 
346  {
347  return iterator (link, 1);
348  }
349 
356  {
357  return ++rend();
358  }
359 
366  {
367  return const_iterator(link, 1);
368  }
369 
378  iterator insert (iterator pos, const T& data);
379 
391  void splice (iterator pos, iterator it);
392 
406 
415 
425 
430 
434  void detach_sublist ();
435 
441  void reverse ();
442 private:
447 
454 
461 };
462 
463 
464 // Implementation Begin
465 
466 template <class T, class Ref>
468 {
469  symnode<T>* prev = act;
470  act = act->adj[dir];
471  dir = where_not(act, prev);
472  return *this;
473 }
474 
475 
476 template <class T, class Ref>
478 {
479  symnode<T>* prev = act;
480  act = act->adj[1 - dir];
481  dir = where(act, prev);
482  return *this;
483 }
484 
485 
486 template <class T>
488 {
489  link = new symnode<T>;
490  link->adj[0] = link->adj[1] = link;
491 
492  const_iterator it = l.begin();
493  const_iterator e = l.end();
494 
495  while (it != e)
496  {
497  insert(end(), *it);
498  ++it;
499  }
500 }
501 
502 
503 template <class T>
505 {
506  if (_next == iterator())
507  {
508  erase (begin(), end());
509  }
510  else
511  {
512  detach_sublist();
513  }
514 
515  delete link;
516 }
517 
518 
519 template <class T>
521 {
522  erase(begin(), end());
523 
524  const_iterator it = l.begin();
525  const_iterator e = l.end();
526 
527  while (it != e)
528  {
529  insert(end(), *it);
530  ++it;
531  }
532 
533  return *this;
534 }
535 
536 
537 template <class T>
540  const T& ins)
541 {
542  iterator prev = pos;
543  --prev;
544  symnode<T>* n = new symnode<T>(ins);
545  n->adj[0] = pos.act;
546  n->adj[1] = prev.act;
547 
548  if (pos == prev)
549  {
550  pos = prev;
551  }
552 
553  pos.prev() = n;
554  prev.next() = n;
555 
556  return iterator(n, 0);
557 }
558 
559 
560 template <class T>
564 {
565  if (beg != end)
566  {
567  iterator prev = beg;
568  --prev;
569  iterator last = end;
570  --last;
571 
572  //
573  // The following seems to be rather senseless, but it is required
574  // since two iterator are equal, iff the point to the same element.
575  // This implies that they might have different directions. Suppose
576  // that prev == end is true and they have different directions,
577  // than prev.next() and end.prev() return the same element !! Thus
578  // the assignment prev = end corrects this, since the direction
579  // gets copied, too.
580  //
581  if (prev == end)
582  {
583  prev = end;
584  }
585 
586  prev.next() = end.act;
587  end.prev() = prev.act;
588 
589  prev = pos;
590  --prev;
591 
592  if (pos == prev)
593  {
594  pos = prev;
595  }
596 
597  if (last == beg)
598  {
599  last = beg;
600  }
601 
602  prev.next() = beg.act;
603  beg.prev() = prev.act;
604  pos.prev() = last.act;
605  last.next() = pos.act;
606  }
607 }
608 
609 
610 template <class T>
613 {
614  iterator tmp = beg;
615  ++tmp;
616  splice(pos, beg, tmp);
617 }
618 
619 
620 template <class T>
622 {
623  assert (pos.act != link);
624  iterator prev = pos;
625  --prev;
626  iterator next = pos;
627  ++next;
628 
629  if (next == prev)
630  {
631  next = prev;
632  }
633 
634  next.prev() = prev.act;
635  prev.next() = next.act;
636 
637  delete (pos.act);
638 
639  return next;
640 }
641 
642 template <class T>
645 {
646  iterator prev = beg;
647  --prev;
648  iterator it = beg;
649  symnode<T>* act;
650 
651  while (it != end)
652  {
653  assert (it.act != link);
654  act = it.act;
655  ++it;
656  delete (act);
657  }
658 
659  if (prev == end)
660  {
661  prev = end;
662  }
663 
664  end.prev() = prev.act;
665  prev.next() = end.act;
666 
667  return end;
668 }
669 
670 
671 template <class T>
674 {
675  assert (empty());
676  iterator last = end;
677  --last;
678  _prev = it;
679  --_prev;
680  _next = end;
681 
682  if (it == last)
683  {
684  it = last;
685  }
686 
687  link->adj[0] = it.act;
688  it.prev() = link;
689  link->adj[1] = last.act;
690  last.next() = link;
691 }
692 
693 
694 template <class T>
696 {
697  if (_next != iterator())
698  {
699  iterator it(begin());
700  iterator e(end());
701 
702  --e;
703 
704  if (e == it)
705  {
706  e = it;
707  }
708 
709  _prev.next() = it.act;
710  it.prev() = _prev.act;
711  _next.prev() = e.act;
712  e.next() = _next.act;
713  link->adj[0] = link->adj[1] = link;
714 
715  _next = iterator();
716  _prev = iterator();
717  }
718 }
719 
720 
721 template <class T>
722 inline void symlist<T>::reverse()
723 {
724  symnode<T>* tmp = link->adj[0];
725  link->adj[0] = link->adj[1];
726  link->adj[1] = tmp;
727 }
728 
729 // Implementation End
730 
732 
733 #endif // SYMLIST_H
734 
735 //--------------------------------------------------------------------------
736 // end of file
737 //--------------------------------------------------------------------------