#ifndef _UTIL_CIRCULAR_QUEUE_H #define _UTIL_CIRCULAR_QUEUE_H #include #include #include template struct CircularQueue { T* base; size_t front; size_t rear; size_t size; }; template bool init_circular_queue(struct CircularQueue& queue, size_t size) { if (size < 2) { return false; } queue.base = (T*)malloc(size * sizeof(T)); if (!queue.base) { return false; } queue.front = 0; queue.rear = 0; queue.size = size; return true; } template void free_circular_queue(struct CircularQueue& queue, std::function free_func = std::function()) { if (!queue.base) return; if (queue.front == queue.rear) return; if (free_func) { circular_queue_iter(queue, free_func); } free(queue.base); queue.base = nullptr; queue.front = 0; queue.rear = 0; queue.size = 0; } template inline void free_circular_queue(struct CircularQueue& queue, F free_func) { free_circular_queue(queue, std::function(free_func)); } template void circular_queue_clear(struct CircularQueue& queue, std::function free_func = std::function()) { if (!queue.base) return; if (free_func && queue.front != queue.rear) { circular_queue_iter(queue, free_func); } queue.front = 0; queue.rear = 0; } template inline void circular_queue_clear(struct CircularQueue& queue, F free_func) { circular_queue_clear(queue, std::function(free_func)); } template bool circular_queue_is_empty(struct CircularQueue& queue) { if (!queue.base) return true; return queue.front == queue.rear; } template bool circular_queue_is_full(struct CircularQueue& queue) { if (!queue.base) return false; return (queue.rear + 1) % queue.size == queue.front; } template size_t circular_queue_length(struct CircularQueue& queue) { if (!queue.base) return 0; return queue.rear >= queue.front ? queue.rear - queue.front : queue.rear + queue.size - queue.front; } template bool circular_queue_get_head(struct CircularQueue& queue, T& head) { if (!queue.base || queue.rear == queue.front) return false; head = queue.base[queue.front]; return true; } template bool circular_queue_get_back(struct CircularQueue& queue, T& back) { if (!queue.base || queue.rear == queue.front) return false; size_t pos = queue.rear ? queue.rear - 1 : queue.size - 1; back = queue.base[pos]; return true; } template bool circular_queue_push(struct CircularQueue& queue, T data) { if (!queue.base) return false; if ((queue.rear + 1) % queue.size == queue.front) return false; queue.base[queue.rear++] = data; queue.rear %= queue.size; return true; } template bool circular_queue_pop(struct CircularQueue& queue, T& data) { if (!queue.base) return false; if (queue.rear == queue.front) return false; data = queue.base[queue.front++]; queue.front %= queue.size; return true; } template void circular_queue_iter(struct CircularQueue& queue, std::function callback, Args... args) { if (!queue.base || !callback) return; if (queue.front == queue.rear) return; size_t now = queue.front; while (now != queue.rear) { callback(queue.base[now], args...); now = (now + 1) % queue.size; } } template inline void circular_queue_iter(struct CircularQueue& queue, F callback, Args... args) { circular_queue_iter(queue, std::function(callback), args...); } #endif