/* $Id: fifo.h,v 1.17 1998/04/19 15:44:31 dps Exp $ */ /* Generalised fifo */ #ifndef __FIFO_H__ #define __FIFO_H__ #include #include #ifndef NULL #define NULL (void *) 0 #endif /* NULL */ template class fifo { private: typedef struct queue { const T *data; struct queue *next; } queue; struct queue *start; struct queue **end; int length; public: inline fifo(void) { start=NULL; end=&start; length=0; } inline int is_empty(void) { #ifdef CONSIST_CHECK if (end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif return (length==0) ? 1 : 0; } inline int qlen(void) { return length; } ~fifo(void); void enqueue(const T *d); /* Add to end of queue */ void insert(const T *d); /* Add to start of queue */ void ins_trans(fifo *f); /* Insert fifo */ void rev(void); /* Reverse */ void clear(void); /* Wipe list to empty */ void transfer(fifo *f); const T *dequeue(void); ostream &__print_fifo(ostream &) const; /* Print */ }; #ifndef __NO_FIFO_FUNCTIONS__ template void fifo::clear(void) { struct queue *ptr, *next; ptr=start; while (ptr!=NULL) { next=ptr->next; delete(ptr->data); delete(ptr); ptr=next; } start=NULL; end=&start; length=0; } template fifo::~fifo(void) { struct queue *ptr, *next; ptr=start; while (ptr!=NULL) { next=ptr->next; delete(ptr->data); delete(ptr); ptr=next; } } template void fifo::enqueue(const T *d) { struct queue *q; #ifdef DEBUG_FIFO cerr<<"Queue "<<(void *) d<<"\n"; #endif q=new(struct queue); q->next=NULL; q->data=d; *end=q; end=&(q->next); length++; } template void fifo::insert(const T *d) { struct queue *q; #ifdef CONSIST_CHECK if (end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif q=new(struct queue); q->next=start; q->data=d; start=q; if (q->next==NULL) end=&(q->next); length++; } template const T *fifo::dequeue(void) { const T *d; struct queue *q; #ifdef CONSIST_CHECK if (end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif if (length==0) return NULL; q=start; d=q->data; #ifdef DEBUG_FIFO cerr<<"Dequeue "<<(void *) d<<"\n"; #endif start=start->next; if (--length==0) end=&start; delete(q); return d; } template void fifo::transfer(fifo *d) { #ifdef CONSIST_CHECK if (end==NULL || d->end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif if (d==NULL || d->length==0) return; *end=d->start; end=d->end; length+=d->length; d->start=NULL; d->end=&(d->start); d->length=0; } template void fifo::ins_trans(fifo *d) { #ifdef CONSIST_CHECK if (end==NULL || d->end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif if (d==NULL || d->length==0) return; *(d->end)=start; start=d->start; if (*(d->end)==NULL) end=d->end; length+=d->length; d->length=0; d->start=NULL; d->end=&(d->start); } template void fifo::rev(void) { struct queue *p, *n, *hdr, **ep; #ifdef CONSIST_CHECK if (end==NULL || d->end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif if (length==0) return; ep=&(start->next); for (hdr=NULL, p=start; p!=NULL; ) { n=p->next; p->next=hdr; hdr=p; p=n; } start=hdr; end=ep; } template ostream &fifo::__print_fifo(ostream &os) const { const struct fifo::queue *q; #ifdef CONSIST_CHECK if (end==NULL || this->end==NULL) { cerr<<"Oops! end of list is NULL\n"; exit(1); } #endif q=this->start; while (q!=NULL) { os<<(q->data)<<','; q=q->next; } return os; } template inline ostream &operator << (ostream &os, const fifo *d) { d->__print_fifo(os); return os; } #endif /* not __NO_FIFO_FUNCTIONS__ */ #endif /* __FIFO_H__ */