1 /* -*- mode: hugs-c; -*- */
2 /* --------------------------------------------------------------------------
3 * Template for generating queues of various types
5 * #define Queue##ChunkSize, Queue and Type before #including this file
6 * to define the following:
8 * typedef { ...; nat len } Queue;
9 * static void insertQueue( Queue* q, Type i );
10 * static void initQueue ( Queue* q );
11 * static void setQueue ( Queue* q, nat i, Type x );
13 * Copyright (c) 1994-1998.
15 * $RCSfile: QueueTemplate.h,v $
17 * $Date: 1998/12/02 13:28:37 $
19 * ------------------------------------------------------------------------*/
21 /* These macros are rather delicate - read a good ANSI C book carefully
25 #define mycat(x,y) x##y
26 #define mycat2(x,y) mycat(x,y)
27 #define mycat3(x,y,z) mycat2(x,mycat2(y,z))
29 typedef struct mycat3(_,Queue,Chunk) {
30 struct mycat3(_,Queue,Chunk)* next;
31 Type xs[mycat2(Queue,ChunkSize)];
32 } mycat2(Queue,Chunk);
34 static mycat2(Queue,Chunk)* mycat3(alloc,Queue,Chunk)( void )
36 mycat2(Queue,Chunk)* new = malloc(sizeof(mycat2(Queue,Chunk)));
38 barf("Can't allomycate " mystr(Queue) "Chunk");
45 mycat2(Queue,Chunk)* head;
46 mycat2(Queue,Chunk)* tail;
47 nat len; /* position of next free instruction */
50 static void mycat2(insert,Queue)( Queue* q, Type i )
53 mycat2(Queue,Chunk)* new = mycat3(alloc,Queue,Chunk)();
57 } else if (q->len % mycat2(Queue,ChunkSize) == 0) {
58 mycat2(Queue,Chunk)* new = mycat3(alloc,Queue,Chunk)();
63 q->tail->xs[q->len % mycat2(Queue,ChunkSize)] = i;
67 static inline void mycat2(init,Queue)( Queue* q )
69 q->head = q->tail = NULL;
73 static void mycat2(set,Queue)( Queue* q, nat i, Type x )
75 mycat2(Queue,Chunk)* chunk = q->head;
77 /* ToDo: optimise case where i is in the last chunk in the list */
78 for(; i >= mycat2(Queue,ChunkSize); i -= mycat2(Queue,ChunkSize)) {
86 /* evaluate a statement s once for every element in a queue q.
87 * i and x are usually free in s
88 * queueTy and eltTy are the types of the container and element respectively
90 #define mapQueue(queueTy,eltTy,q,s) \
92 mycat2(queueTy,Chunk)* chunk = (q).head; \
95 while( i < (q).len ) { \
97 x = chunk->xs[i % mycat2(queueTy,ChunkSize)]; \
100 if (i % mycat2(queueTy,ChunkSize) == 0) { \
101 chunk = chunk->next; \
106 /* --------------------------------------------------------------------------
107 * End of Queue template
108 * ------------------------------------------------------------------------*/