home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / Queue.h < prev    next >
C/C++ Source or Header  |  1998-03-25  |  5KB  |  249 lines

  1. // $Id: Queue.h,v 1.13 1998/03/25 12:44:02 zeller Exp $  -*- C++ -*-
  2. // Queue template
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of the ICE Library.
  8. // 
  9. // The ICE Library is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU Library General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // The ICE Library is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU Library General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU Library General Public
  20. // License along with the ICE Library -- see the file COPYING.LIB.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // ICE is the incremental configuration environment.
  25. // For details, see the ICE World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ice/',
  27. // or send a mail to the ICE developers <ice@ips.cs.tu-bs.de>.
  28.  
  29. #ifndef _ICE_Queue_h
  30. #define _ICE_Queue_h
  31.  
  32. #if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 5)
  33. #pragma interface
  34. #endif
  35.  
  36. #include "bool.h"
  37. #include "assert.h"
  38.  
  39. template<class E>
  40. struct QueueRec {
  41.     E elem;
  42.     QueueRec<E> *next;
  43.  
  44.     // Constructor
  45.     QueueRec(const E& e)
  46.         : elem(e), next(0)
  47.     {}
  48.  
  49. private:
  50.     QueueRec(const QueueRec<E>& qr)
  51.     : elem(qr.elem), next(0)
  52.     {
  53.     assert(0);
  54.     }
  55.  
  56.     QueueRec<E>& operator = (const QueueRec<E>&)
  57.     {
  58.     assert(0); return *this;
  59.     }
  60. };
  61.  
  62. template<class E>
  63. class QueueIter;
  64.  
  65. template<class E>
  66. class Queue {
  67. private:
  68.     QueueRec<E> *_first;
  69.     QueueRec<E> *_last;
  70.  
  71.     // For QueueIter only
  72.     QueueRec<E> *firstRec() const { return _first; }
  73.  
  74.     friend class QueueIter<E>;
  75.  
  76. protected:
  77.     // Remove all elements
  78.     void clear()
  79.     {
  80.         QueueRec<E> *rec = _first;   // loop var
  81.     while (rec != 0)
  82.     {
  83.         QueueRec<E> *kill = rec;
  84.         rec = rec->next;
  85.         delete kill;
  86.     }
  87.  
  88.     _first = 0;
  89.     _last  = 0;
  90.     }
  91.  
  92.     // Copy and add elements from E
  93.     void add(const Queue<E>& e)
  94.     {
  95.     for (QueueIter<E> i = e; i.ok(); i = i.next())
  96.         operator += (i());
  97.     }
  98.  
  99. public:
  100.     // Constructor
  101.     Queue(): 
  102.         _first(0), _last(0)
  103.     {}
  104.  
  105.     // Destructor
  106.     ~Queue()
  107.     {
  108.     clear();
  109.     }
  110.  
  111.     // Copy Constructor
  112.     Queue(const Queue<E>& e): 
  113.         _first(0), _last(0)
  114.     {
  115.     add(e);
  116.     }
  117.  
  118.     // Assignment
  119.     Queue<E>& operator = (const Queue<E>& e)
  120.     {
  121.     if (&e != this)
  122.     {
  123.         clear();
  124.         add(e);
  125.     }
  126.     return *this;
  127.     }
  128.  
  129.     // Add at end
  130.     void enqueue_at_end(const E& e)
  131.     {
  132.     QueueRec<E> *rec = new QueueRec<E>(e);
  133.     if (_last == 0)
  134.         _first = rec;
  135.     else
  136.         _last->next = rec;
  137.     _last = rec;
  138.     }
  139.  
  140.     // Add after A
  141.     void enqueue_after(const E& e, QueueIter<E> a)
  142.     {
  143.     QueueRec<E> *rec = new QueueRec<E>(e);
  144.     QueueRec<E> *after = a.theRec();
  145.     rec->next = after->next;
  146.     after->next = rec;
  147.     if (after == _last)
  148.         _last = rec;
  149.     }
  150.  
  151.     // Add at start
  152.     void enqueue_at_start(const E& e)
  153.     {
  154.     QueueRec<E> *rec = new QueueRec<E>(e);
  155.     rec->next = _first;
  156.     if (_first == _last)
  157.         _last = rec;
  158.     _first = rec;
  159.     }
  160.  
  161.     // Remove
  162.     void dequeue(const E& e)
  163.     {
  164.     QueueRec<E> *prev = 0;       // kill predecessor
  165.         QueueRec<E> *rec = _first;   // loop var
  166.  
  167.     while (rec != 0)
  168.     {
  169.         QueueRec<E> *kill = rec;
  170.         rec = rec->next;
  171.  
  172.         if (kill->elem == e)
  173.         {
  174.         // setup _last
  175.         if (kill == _last)
  176.             _last = prev;
  177.  
  178.         // dequeue kill
  179.         if (prev == 0)
  180.             _first = kill->next;
  181.         else
  182.             prev->next = kill->next;
  183.  
  184.         // kill it
  185.         delete kill;
  186.  
  187.         // don't search for further occurrences
  188.         break;
  189.         }
  190.         else
  191.         prev = kill;
  192.     }
  193.     }
  194.  
  195.     // Operator versions
  196.     void operator += (const E& e) { enqueue_at_end(e); }
  197.     void operator -= (const E& e) { dequeue(e); }
  198.  
  199.     // Access
  200.     const E& first() const { return _first->elem; }
  201.     const E& last()  const { return _last->elem; }
  202.     E& first()             { return _first->elem; }
  203.     E& last()              { return _last->elem; }
  204.  
  205.     // Testing
  206.     bool isEmpty() const { return _first == 0; }
  207. };
  208.  
  209. template<class E>
  210. class QueueIter {
  211. private:
  212.     QueueRec<E> *rec;
  213.     QueueIter(QueueRec<E> *ptr):
  214.         rec(ptr)
  215.     {}
  216.  
  217.     // For Queue only
  218.     QueueRec<E> *theRec() const { return rec; }
  219.  
  220.     friend class Queue<E>;
  221.  
  222. public:
  223.     QueueIter(const Queue<E>& queue):
  224.         rec(queue.firstRec())
  225.     {}
  226.     QueueIter(const QueueIter<E>& iter):
  227.         rec(iter.rec)
  228.     {}
  229.     QueueIter<E>& operator = (const QueueIter<E>& iter)
  230.     {
  231.     rec = iter.rec;
  232.     return *this;
  233.     }
  234.     QueueIter<E>& operator = (const Queue<E>& queue)
  235.     {
  236.     rec = queue.firstRec();
  237.     return *this;
  238.     }
  239.  
  240.     const E& operator()() const { return rec->elem; }
  241.     E& operator()()             { return rec->elem; }
  242.  
  243.     bool ok() const { return rec != 0; }
  244.     QueueIter<E> next() const { return QueueIter<E>(rec->next); }
  245. };
  246.  
  247. #endif // _ICE_Queue_h
  248. // DON'T ADD ANYTHING BEHIND THIS #endif
  249.