Initial import
This commit is contained in:
99
src/queue.h
Normal file
99
src/queue.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
* queue.h - macros for defining a double-ended queue
|
||||
*
|
||||
* Copyright (C) 2015 by David A. Baer, All Rights Reserved
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* These macros are designed to make it easier to process input whose
|
||||
* length is unknown before it terminates (e.g. a series of numbers).
|
||||
* The APPEND_QUEUE macro adds a new element to the list. The
|
||||
* QUEUE_LENGTH macro provides the current length of the queue. The
|
||||
* QUEUE_TO_ARRAY macro can convert the queue into a more compact
|
||||
* array.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* DEFINE_QUEUE(MyType, QueueOfMyType);
|
||||
* NEW_QUEUE(QueueOfMyType, myq);
|
||||
* APPEND_QUEUE(QueueOfMyType, myq, VALUE1);
|
||||
* APPEND_QUEUE(QueueOfMyType, myq, VALUE2);
|
||||
* ...
|
||||
* FOREACH_QUEUE(QueueOfMyType, myq, iterator) {
|
||||
* (some action)
|
||||
* }
|
||||
* FOREACH_QUEUE_END <--- NOTE: THIS IS MANDATORY
|
||||
* len = QUEUE_LENGTH(myq);
|
||||
* QUEUE_TO_ARRAY(QueueOfMyType, myq, MyType, targetptr);
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef _QUEUE_H
|
||||
#define _QUEUE_H
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEFINE_QUEUE(T, N) \
|
||||
struct _##N##Node { \
|
||||
T data; \
|
||||
struct _##N##Node* next; \
|
||||
};\
|
||||
typedef struct { \
|
||||
int length; \
|
||||
struct _##N##Node *head, *tail; \
|
||||
} N
|
||||
|
||||
#define NEW_QUEUE(T, N) \
|
||||
T N = (T) { .length = 0, .head = NULL, .tail = NULL }
|
||||
|
||||
#define APPEND_QUEUE(T, Q, E) { \
|
||||
struct _##T##Node* n = (struct _##T##Node*)malloc(sizeof(struct _##T##Node)); \
|
||||
if (!n) { perror ("Could not allocate space for new queue element."); exit(1); } \
|
||||
n->data = E; \
|
||||
n->next = NULL; \
|
||||
if ((Q).head == NULL) (Q).head = n; \
|
||||
if ((Q).tail != NULL) (Q).tail->next = n; \
|
||||
(Q).tail = n; \
|
||||
(Q).length++; \
|
||||
}
|
||||
|
||||
#define QUEUE_LENGTH(Q) Q.length
|
||||
|
||||
#define FOREACH_QUEUE(T, Q, N) { \
|
||||
struct _##T##Node* N = NULL; \
|
||||
for (N = (Q).head; N != NULL; N = (N)->next)
|
||||
|
||||
#define FOREACH_QUEUE_END }
|
||||
|
||||
#define DESTROY_QUEUE(T, Q) { \
|
||||
struct _##T##Node* ptr = (Q).head; \
|
||||
while (ptr != NULL) { \
|
||||
struct _##T##Node* temp = ptr->next; \
|
||||
free(ptr); \
|
||||
ptr = temp; \
|
||||
} \
|
||||
(Q).head = (Q).tail = NULL; \
|
||||
(Q).length = 0; \
|
||||
}
|
||||
|
||||
#define DESTROY_QUEUE_FUNC(T, Q, F) { \
|
||||
struct _##T##Node* ptr = (Q).head; \
|
||||
while (ptr != NULL) { \
|
||||
struct _##T##Node* temp = ptr->next; \
|
||||
F(ptr->data); \
|
||||
free(ptr); \
|
||||
ptr = temp; \
|
||||
} \
|
||||
(Q).head = (Q).tail = NULL; \
|
||||
(Q).length = 0; \
|
||||
}
|
||||
|
||||
#define QUEUE_TO_ARRAY(QT, Q, T, DST) { \
|
||||
int i = 0; \
|
||||
DST = (T*)calloc(Q.length,sizeof(T)); \
|
||||
if (!DST) { perror("Could not allocate space for array."); exit(1); } \
|
||||
FOREACH_QUEUE(QT, Q, ptr) \
|
||||
DST[i++] = ptr->data; \
|
||||
FOREACH_QUEUE_END; \
|
||||
}
|
||||
|
||||
#endif /* !def _QUEUE_H */
|
||||
Reference in New Issue
Block a user