1 /* -*- mode: hugs-c; -*- */
2 /* -----------------------------------------------------------------------------
3 * $Id: QueueTemplate.h,v 1.3 1999/02/05 16:02:48 simonm Exp $
5 * (c) The GHC Team, 1998
7 * Template for generating queues of various types
9 * #define Queue##ChunkSize, Queue and Type before #including this file
10 * to define the following:
12 * typedef { ...; nat len } Queue;
13 * static void insertQueue( Queue* q, Type i );
14 * static void initQueue ( Queue* q );
15 * static void setQueue ( Queue* q, nat i, Type x );
17 * Copyright (c) 1994-1998.
19 * $RCSfile: QueueTemplate.h,v $
21 * $Date: 1999/02/05 16:02:48 $
23 * ------------------------------------------------------------------------*/
25 /* These macros are rather delicate - read a good ANSI C book carefully
29 #define mycat(x,y) x##y
30 #define mycat2(x,y) mycat(x,y)
31 #define mycat3(x,y,z) mycat2(x,mycat2(y,z))
33 typedef struct mycat3(_,Queue,Chunk) {
34 struct mycat3(_,Queue,Chunk)* next;
35 Type xs[mycat2(Queue,ChunkSize)];
36 } mycat2(Queue,Chunk);
38 static mycat2(Queue,Chunk)* mycat3(alloc,Queue,Chunk)( void )
40 mycat2(Queue,Chunk)* new = malloc(sizeof(mycat2(Queue,Chunk)));
42 barf("Can't allomycate " mystr(Queue) "Chunk");
49 mycat2(Queue,Chunk)* head;
50 mycat2(Queue,Chunk)* tail;
51 nat len; /* position of next free instruction */
54 static void mycat2(insert,Queue)( Queue* q, Type i )
57 mycat2(Queue,Chunk)* new = mycat3(alloc,Queue,Chunk)();
61 } else if (q->len % mycat2(Queue,ChunkSize) == 0) {
62 mycat2(Queue,Chunk)* new = mycat3(alloc,Queue,Chunk)();
67 q->tail->xs[q->len % mycat2(Queue,ChunkSize)] = i;
71 static inline void mycat2(init,Queue)( Queue* q )
73 q->head = q->tail = NULL;
77 static void mycat2(set,Queue)( Queue* q, nat i, Type x )
79 mycat2(Queue,Chunk)* chunk = q->head;
81 /* ToDo: optimise case where i is in the last chunk in the list */
82 for(; i >= mycat2(Queue,ChunkSize); i -= mycat2(Queue,ChunkSize)) {
90 /* evaluate a statement s once for every element in a queue q.
91 * i and x are usually free in s
92 * queueTy and eltTy are the types of the container and element respectively
94 #define mapQueue(queueTy,eltTy,q,s) \
96 mycat2(queueTy,Chunk)* chunk = (q).head; \
99 while( i < (q).len ) { \
101 x = chunk->xs[i % mycat2(queueTy,ChunkSize)]; \
104 if (i % mycat2(queueTy,ChunkSize) == 0) { \
105 chunk = chunk->next; \
110 /* --------------------------------------------------------------------------
111 * End of Queue template
112 * ------------------------------------------------------------------------*/