You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
7.4 KiB
C

3 years ago
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define MAX_QUEUE_SIZE (512)
typedef enum PB_STATUS
{
PB_GOOD = 0,
PB_BAD = 1,
PB_BAD_BUFFER_SIZE = 2,
PB_NULL_BUFFER = 3,
PB_NULL_DATA = 4,
PB_EMPTY_QUEUE = 5,
PB_FULL_QUEUE = 6
} PB_STATUS;
// This macro defines a queue type. It doesn't make a queue for you.
// See below for an example on how to make a queue.
// Creates a type of queue_${type}_t of size ${size}.
// the size will be fixed for all instances of that type unfortunately.
#define QUEUE(type, size) \
typedef struct queue_##type##_t \
{ \
int data[size]; \
int head; \
int tail; \
int msize; \
int csize; \
\
PB_STATUS (*enqueue)(struct queue_##type##_t * queue, type val); \
PB_STATUS (*dequeue)(struct queue_##type##_t * queue, type* val); \
void (*empty)(struct queue_##type##_t * queue); \
bool (*is_full)(struct queue_##type##_t * queue); \
\
} queue_##type##_t; \
\
bool queue_##type##_is_full(queue_##type##_t* queue) \
{ \
return (queue->csize == queue->msize); \
} \
\
void queue_##type##_empty(queue_##type##_t* queue) \
{ \
memset(queue->data, 0, sizeof(type) * queue->msize); \
queue->head = -1; \
queue->tail = -1; \
queue->csize = 0; \
} \
\
PB_STATUS queue_##type##_enqueue(queue_##type##_t* queue, type val) \
{ \
PB_STATUS ret = PB_GOOD; \
if (queue->is_full(queue)) \
{ \
ret = PB_FULL_QUEUE; \
} \
else \
{ \
if (queue->head == -1) \
{ \
queue->head = 0; \
queue->csize = 0; \
queue->tail = queue->msize - 1; \
} \
queue->tail = (queue->tail + 1) % queue->msize; \
queue->data[queue->tail] = val; \
queue->csize++; \
} \
return ret; \
} \
\
PB_STATUS queue_##type##_dequeue(queue_##type##_t* queue, type* val) \
{ \
PB_STATUS ret = PB_GOOD; \
if (queue->csize == 0) \
{ \
ret = PB_EMPTY_QUEUE; \
} \
else \
{ \
*val = queue->data[queue->head]; \
queue->head = (queue->head + 1) % queue->csize; \
queue->csize -= 1; \
} \
return ret; \
} \
PB_STATUS queue_##type##_init(queue_##type##_t* queue) \
{ \
PB_STATUS ret = PB_GOOD; \
do \
{ \
if (!queue) \
{ \
ret = PB_NULL_BUFFER; \
break; \
} \
\
if (size > MAX_QUEUE_SIZE || size <= 0) \
{ \
ret = PB_BAD_BUFFER_SIZE; \
break; \
} \
} while (0); \
queue->msize = size; \
queue->head = -1; \
queue->tail = -1; \
queue->csize = 0; \
queue->enqueue = queue_##type##_enqueue; \
queue->dequeue = queue_##type##_dequeue; \
queue->empty = queue_##type##_empty; \
queue->is_full = queue_##type##_is_full; \
return ret; \
}
// Example:
// QUEUE(int, 4);
// queue_int_t queue;
// // in .c
// queue_int_init(&queue);
#endif