#ifndef _UTIL_LINKED_QUEUE_H #define _UTIL_LINKED_QUEUE_H #include #include #include template struct LinkedQueueNode { T d; struct LinkedQueueNode* next; }; template struct LinkedQueue { struct LinkedQueueNode* front; struct LinkedQueueNode* rear; }; template void linked_queue_init(struct LinkedQueue& queue) { queue.front = nullptr; queue.rear = nullptr; } template size_t linked_queue_length(struct LinkedQueue& queue) { if (!queue.front) return 0; struct LinkedQueueNode* node = queue.front; size_t i = 1; while (node->next) { node = node->next; i++; } return i; } template void free_linked_queue(struct LinkedQueue& queue, std::function free_func = std::function()) { if (!queue.front) return; struct LinkedQueueNode* node = queue.front, *tmp = queue.front; do { tmp = node; node = node->next; if (free_func) { free_func(tmp->d); } free(tmp); } while (node); queue.front = nullptr; queue.rear = nullptr; } template inline void free_linked_queue(struct LinkedQueue& queue, F free_func) { free_linked_queue(queue, std::function(free_func)); } template bool linked_queue_push(struct LinkedQueue& queue, T data) { struct LinkedQueueNode* node = (struct LinkedQueueNode*)malloc(sizeof(struct LinkedQueueNode)); if (!node) { return false; } node->d = data; node->next = nullptr; if (queue.rear) { queue.rear->next = node; } else { queue.front = node; } queue.rear = node; return true; } template bool linked_queue_pop(struct LinkedQueue& queue, T& data) { if (!queue.front) return false; data = queue.front->d; struct LinkedQueueNode* tmp = queue.front; if (!tmp->next) { queue.rear = nullptr; } queue.front = tmp->next; free(tmp); return true; } template void linked_queue_iter(struct LinkedQueue& queue, std::function callback, Args... args) { if (!queue.front || !callback) return; struct LinkedQueueNode* node = queue.front; do { callback(node->d, args...); node = node->next; } while (node); } template inline void linked_queue_iter(struct LinkedQueue& queue, F callback, Args... args) { linked_queue_iter(queue, std::function(callback), args...); } #endif