#ifndef _ALGO_QUEUE_H_
#define _ALGO_QUEUE_H_

/* 队列类型定义 */
typedef struct QUEUE
{
    void* base;         /* 数据存储区的基地址 */
    int dsize;          /* 每个数据元素的大小（字节） */
    int capacity;       /* 队列的总容量（最大元素数量） */
    int size;           /* 当前队列中的元素数量 */
    int head;           /* 队头索引（指向第一个元素） */
    int tail;           /* 队尾索引（指向下一个插入位置） */
} *queue;  // 定义queue为指向该结构的指针类型

/**
 *  \brief 创建并初始化一个队列
 *  \param[in] type: 队列元素的数据类型
 *  \param[in] capacity: 队列容量
 *  \return 初始化完成的队列对象
 *  
 *  \note 使用复合字面量在栈上创建队列对象
 *  \example queue(int, 10) 创建容量为10的整型队列
 */
#define queue(type, capacity)           (&(struct QUEUE){(type[capacity]){0},sizeof(type),capacity,0,0,0})

// 函数声明
int queue_push(queue queue, void* data);
int queue_push2(queue queue, void* data);
int queue_pop(queue queue, void* data);
int queue_insert(queue queue, int index, void* data);
int queue_erase(queue queue, int index, void* data);
void queue_clear(queue queue);
void* queue_data(queue queue, int index);

/**
 *  \brief 访问队列指定位置的元素
 *  \param[in] queue: 队列对象
 *  \param[in] type: 元素数据类型
 *  \param[in] i: 元素位置索引（0-based）
 *  \return 指定元素的左值引用
 *  
 *  \example queue_at(q, int, 0) = 42; // 设置队首元素
 */
#define queue_at(queue, type, i)        (*(type *)queue_data((queue),(i)))

/**
 *  \brief 在队头插入元素
 *  \param[in] queue: 队列对象
 *  \param[in] data: 待插入数据地址（NULL表示不赋值）
 *  \return 操作成功状态（1成功/0失败）
 */
#define queue_push_front(queue, data)   queue_insert((queue), 0, data)

/**
 *  \brief 在队尾插入元素
 *  \param[in] queue: 队列对象
 *  \param[in] data: 待插入数据地址（NULL表示不赋值）
 *  \return 操作成功状态（1成功/0失败）
 */
#define queue_push_back(queue, data)    queue_push2((queue), data)

/**
 *  \brief 从队头弹出元素
 *  \param[in] queue: 队列对象
 *  \param[out] data: 接收弹出数据的地址（NULL表示不保存）
 *  \return 操作成功状态（1成功/0失败）
 */
#define queue_pop_front(queue, data)    queue_pop((queue), data)

/**
 *  \brief 从队尾弹出元素
 *  \param[in] queue: 队列对象
 *  \param[out] data: 接收弹出数据的地址（NULL表示不保存）
 *  \return 操作成功状态（1成功/0失败）
 */
#define queue_pop_back(queue, data)     queue_erase((queue), (queue)->size - 1, data)

/**
 *  \brief 获取队列当前元素数量
 *  \param[in] queue: 队列对象
 *  \return 队列中的元素数量
 */
#define queue_size(queue)               ((queue)->size)

/**
 *  \brief 获取队列总容量
 *  \param[in] queue: 队列对象
 *  \return 队列的最大容量
 */
#define queue_capacity(queue)           ((queue)->capacity)

/**
 *  \brief 检查队列是否为空
 *  \param[in] queue: 队列对象
 *  \return 0表示非空，非0表示空
 */
#define queue_empty(queue)              ((queue)->size == 0)

/**
 *  \brief 检查队列是否已满
 *  \param[in] queue: 队列对象
 *  \return 0表示未满，非0表示已满
 */
#define queue_full(queue)               ((queue)->size == (queue)->capacity)

/** 
 *  \brief 创建字面量的地址包装
 *  \param[in] type: 数据类型（如int/float等）
 *  \param[in] value: 字面量值
 *  \return 包含该值的临时数组地址
 *  
 *  \note 用于将字面量转换为指针参数
 *  \example queue_push(q, literal(int, 42));
 */
#ifndef literal
#define literal(type, value)            ((type[1]){value})
#endif

#endif
