如下所示,準備兩個宏,一個定義類型,一個定義容器大小。
使用時只要先定義這兩個宏,然后再包含容器頭文件就能生成不同類型和大小的容器了。但是這種方法只允許在源文件中使用,如果在頭文件中使用,定義不同類型和大小的容器時會引起宏定義沖突。
#pragma once
#include "cb/cb_define.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>#ifdef __cplusplus
extern "C"
{
#endif////// @brief 模板參數。隊列元素類型。///
#ifndef __template_cb_circle_deque_element_type#define __template_cb_circle_deque_element_type int
#endif////// @brief 模板參數。隊列大小。///
#ifndef __template_cb_circle_deque_size#define __template_cb_circle_deque_size 100
#endif////// @brief 循環隊列。///typedef struct cb_circle_deque{__template_cb_circle_deque_element_type _buffer[__template_cb_circle_deque_size];uint32_t _begin;uint32_t _end;bool _is_full;} cb_circle_deque;////// @brief 初始化。////// @param self/// @return///__cb_force_inline void cb_circle_deque_initialize(cb_circle_deque *self){self->_begin = 0;self->_end = 0;self->_is_full = false;}////// @brief 隊列中的元素個數。////// @param self/// @return///__cb_force_inline int cb_circle_deque_count(cb_circle_deque *self){if (self->_is_full){return __template_cb_circle_deque_size;}if (self->_end >= self->_begin){return self->_end - self->_begin;}return __template_cb_circle_deque_size - (self->_begin - self->_end);}////// @brief 隊列為空。////// @param self/// @return///__cb_force_inline bool cb_circle_deque_is_empty(cb_circle_deque *self){return self->_begin == self->_end && !self->_is_full;}////// @brief 向隊列末尾添加元素。////// @param self/// @param value/// @return 添加成功返回 true, 添加失敗返回 false.///__cb_force_inline bool cb_circle_deque_push_back(cb_circle_deque *self,__template_cb_circle_deque_element_type *value){if (value == NULL){return false;}if (self->_is_full){return false;}self->_buffer[self->_end] = *value;self->_end = (self->_end + 1) % __template_cb_circle_deque_size;if (self->_end == self->_begin){self->_is_full = true;}return true;}////// @brief 向隊列頭部添加元素。////// @param self/// @param value/// @return 添加成功返回 true, 添加失敗返回 false.///__cb_force_inline bool cb_circle_deque_push_front(cb_circle_deque *self,__template_cb_circle_deque_element_type *value){if (value == NULL){return false;}if (self->_is_full){return false;}self->_begin = (self->_begin + __template_cb_circle_deque_size - 1) % __template_cb_circle_deque_size;self->_buffer[self->_begin] = *value;if (self->_end == self->_begin){self->_is_full = true;}return true;}////// @brief 彈出隊列末尾元素。////// @param self/// @param out/// @return///__cb_force_inline bool cb_circle_deque_pop_back(cb_circle_deque *self,__template_cb_circle_deque_element_type *out){if (cb_circle_deque_is_empty(self)){return false;}self->_end = (self->_end + __template_cb_circle_deque_size - 1) % __template_cb_circle_deque_size;if (out != NULL){*out = self->_buffer[self->_end];}self->_is_full = false;return true;}////// @brief 彈出隊列頭部元素。////// @param self/// @param out/// @return///__cb_force_inline bool cb_circle_deque_pop_front(cb_circle_deque *self,__template_cb_circle_deque_element_type *out){if (cb_circle_deque_is_empty(self)){return false;}if (out != NULL){*out = self->_buffer[self->_begin];}self->_begin = (self->_begin + 1) % __template_cb_circle_deque_size;self->_is_full = false;return true;}////// @brief 獲取隊列中指定索引的元素。////// @param self/// @param index////// @return 如果指定索引處有元素,則返回該元素的指針,否則返回空指針。///__cb_force_inline __template_cb_circle_deque_element_type *cb_circle_deque_get(cb_circle_deque *self,int index){if (index < 0 || index >= cb_circle_deque_count(self)){return NULL;}uint32_t pos = (self->_begin + index) % __template_cb_circle_deque_size;return &self->_buffer[pos];}////// @brief 清空隊列。////// @param self/// @return///__cb_force_inline void cb_circle_deque_clear(cb_circle_deque *self){self->_begin = 0;self->_end = 0;self->_is_full = false;}#ifdef __cplusplus
}
#endif