home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / aetsk100.arj / SYSQTMPL.H < prev    next >
C/C++ Source or Header  |  1991-11-13  |  6KB  |  271 lines

  1. /*
  2.     sysqueue.h
  3.  
  4.     templates for queues using double linked lists
  5.  
  6.     copyright (c) 1991 J. Alan Eldridge
  7.     
  8.     history:
  9.     
  10.     10/28/91    created
  11.     
  12.     10/30/91    changed class hierarchy so we now have:
  13.     
  14.                 SysQ<T>     queue of Ts
  15.                 SysPriQ<T>  priority queue of Ts
  16.                 SysQP<T>    queue of ptrs to T
  17.                 SysPriQP<T> priority queue of ptrs to T
  18.  
  19. */
  20.  
  21. template <class T> struct SysQNode {
  22.     T           data;
  23.     SysQNode<T> *next;
  24.     SysQNode<T> *prev;
  25. };
  26.     
  27. template <class T> class SysQ {
  28. protected:
  29.     int         nused, nfree, maxnodes;
  30.     SysQNode<T> *head, *tail, *free;
  31.  
  32.     SysQNode<T> *getfree(int=1);
  33.     void        putfree(SysQNode<T>*);
  34.  
  35.     SysQNode<T>         *findnode(T);
  36.     virtual SysQNode<T> *findpred(T);
  37.     
  38.     void        create(SysQNode<T>*);
  39.     void        insert(SysQNode<T>*, SysQNode<T>*);
  40.  
  41.     int         Ins(T);
  42. public:
  43.     SysQ(int n=0, int lim=INT_MAX);
  44.     ~SysQ();
  45.     int         Add(T);
  46.     int         Del(T);
  47.     int         Get(T&, int=1);
  48.     int         Cnt()
  49.         { return nused; }
  50.     int         Max()
  51.         { return maxnodes; }
  52. };
  53.  
  54. template <class T>
  55. SysQ<T>::SysQ(int n, int lim)
  56. {
  57.     nused = nfree = 0;
  58.     head = tail = free = 0;
  59.     maxnodes = lim;
  60.     while (n-- > 0)
  61.         putfree(new SysQNode<T>);
  62. }
  63.  
  64. template <class T>
  65. SysQ<T>::~SysQ()
  66. {
  67.     T           t;
  68.     SysQNode<T> *pn;
  69.     
  70.     //  dump all nodes onto free list
  71.     while (Get(t))
  72.         ;
  73.     //  delete all nodes on free list
  74.     while ((pn = getfree(0)) != 0)
  75.         delete pn;
  76. }
  77.  
  78. template <class T> SysQNode<T>*
  79. SysQ<T>::getfree(int alloc)
  80. {
  81.     SysQNode<T>   *pn = 0;
  82.  
  83.     if (nfree > 0) {
  84.         pn = free;
  85.         free = free->next;
  86.         nfree--;
  87.     } else if (alloc) {
  88.         pn = new SysQNode<T>;
  89.     }
  90.     
  91.     return pn;
  92. }
  93.  
  94. template <class T> void
  95. SysQ<T>::putfree(SysQNode<T> *pn)
  96. {
  97.     nfree++;
  98.     pn->next = free;
  99.     free = pn;
  100. }
  101.  
  102. template <class T> SysQNode<T>*
  103. SysQ<T>::findnode(T t)
  104. {
  105.     SysQNode<T> *pn = head;
  106.     
  107.     while (pn && !(pn->data == t))
  108.         pn = pn->next;
  109.     
  110.     return pn;
  111. }
  112.  
  113. template <class T> void
  114. SysQ<T>::create(SysQNode<T> *pn)
  115. {
  116.     head = tail = pn;
  117.     nused = 1;
  118.     pn->prev = pn->next = 0;
  119. }
  120.  
  121. template <class T> void
  122. SysQ<T>::insert(SysQNode<T> *pnext, SysQNode<T> *pn)
  123. {
  124.     //  add before 0 means put at tail
  125.  
  126.     if (!nused)
  127.         create(pn);
  128.     else {
  129.         if (pnext) {
  130.             pn->prev = pnext->prev;
  131.             if (pnext == head)
  132.                 head = pn;
  133.             else
  134.                 pnext->prev->next = pn;
  135.             pnext->prev = pn;
  136.             pn->next = pnext;
  137.         } else {
  138.             pn->prev = tail;
  139.             tail->next = pn;
  140.             tail = pn;
  141.             pn->next = 0;
  142.         }
  143.         nused++;
  144.     }
  145. }
  146.         
  147. template <class T> int
  148. SysQ<T>::Add(T t)
  149. {
  150.     SysQNode<T> *pn = getfree(nused + nfree < maxnodes);
  151.     
  152.     if (pn) {
  153.         pn->data = t;
  154.         insert(0, pn);
  155.     }
  156.  
  157.     return !!pn;
  158. }
  159.  
  160. template <class T> SysQNode<T>*
  161. SysQ<T>::findpred(T t)
  162. {
  163.     SysQNode<T> *pwalk;
  164.     
  165.     pwalk = head;
  166.     while (pwalk && !(pwalk->data < t))
  167.         pwalk = pwalk->next;
  168.     return pwalk;
  169. }
  170.         
  171. template <class T> int
  172. SysQ<T>::Ins(T t)
  173. {
  174.     SysQNode<T> *pn = getfree(nused + nfree < maxnodes);
  175.  
  176.     if (pn) {
  177.         pn->data = t;
  178.         insert(findpred(t), pn);
  179.     }
  180.     
  181.     return !!pn;
  182. }
  183.  
  184. template <class T> int
  185. SysQ<T>::Get(T& t, int rmv)
  186. {
  187.     SysQNode<T> *pn = head;
  188.     
  189.     if (pn) {
  190.         t = head->data;
  191.         if (rmv) {
  192.             if ((head = head->next) != 0)
  193.                 head->prev = 0;
  194.             else
  195.                 tail = 0;
  196.             nused--;
  197.             putfree(pn);
  198.         }
  199.     }
  200.     
  201.     return !!pn;
  202. }
  203.  
  204. template <class T> int
  205. SysQ<T>::Del(T t)
  206. {
  207.     SysQNode<T> *pn = findnode(t);
  208.     
  209.     if (pn) {
  210.         if (nused == 1)
  211.             head = tail = 0;
  212.         else if (pn == head) 
  213.             (head = head->next)->prev = 0;
  214.         else if (pn == tail)
  215.             (tail = tail->prev)->next = 0;
  216.         else {
  217.             pn->next->prev = pn->prev;
  218.             pn->prev->next = pn->next;
  219.         }
  220.         nused--;
  221.         putfree(pn);
  222.     }
  223.     
  224.     return !!pn;
  225. }
  226.  
  227. template <class T> class SysPriQ: public SysQ<T> {
  228. public:
  229.     SysPriQ(int n=0, int lim=INT_MAX): SysQ<T>(n,lim) { }
  230.     int Add(T t)
  231.         { return SysQ<T>::Ins(t); }
  232. };
  233.  
  234. template <class T> class SysQP: public SysQ<void *> {
  235. protected:
  236.     SysQNode<void*> *findpred(void *);
  237. public:
  238.     SysQP(int n=0,int lim=INT_MAX): SysQ<void*>(n,lim) { }
  239.     int Add(T* t)
  240.         { return SysQ<void*>::Add(t); }
  241.     int Del(T* t)
  242.         { return SysQ<void*>::Del(t); }
  243.     int Get(T* &t,int rmv=1)
  244.         { return SysQ<void*>::Get((void*&)t,rmv); }
  245.     T*  Get(int rmv=1);
  246. };
  247.  
  248. template <class T> SysQNode<void*>*
  249. SysQP<T>::findpred(void *p)
  250. {
  251.     SysQNode<void*> *pwalk;
  252.     
  253.     pwalk = head;
  254.     while (pwalk && !(*(T*)pwalk->data < *(T*)p))
  255.         pwalk = pwalk->next;
  256.     return pwalk;
  257. }
  258.         
  259. template <class T> T* SysQP<T>::Get(int rmv)
  260. {
  261.     T   *t;
  262.     return Get(t,rmv) ? t : 0;
  263. }
  264.  
  265. template <class T> class SysPriQP: public SysQP<T> {
  266. public:
  267.     SysPriQP(int n=0, int lim=INT_MAX): SysQP<T>(n,lim) { }
  268.     int Add(T* t)
  269.         { return SysQP<T>::Ins(t); }
  270. };
  271.