#ifndef LIBA_VEC_H
#define LIBA_VEC_H
#include "a.h"
typedef struct a_vec
{
void *ptr_;
a_size siz_;
a_size num_;
a_size mem_;
} a_vec;
A_INTERN void *a_vec_ptr(a_vec const *ctx) { return ctx->ptr_; }
#define A_VEC_PTR(T, ctx) a_cast_s(T *, a_vec_ptr(ctx))
A_INTERN a_size a_vec_siz(a_vec const *ctx) { return ctx->siz_; }
A_INTERN a_size a_vec_num(a_vec const *ctx) { return ctx->num_; }
A_INTERN a_size a_vec_mem(a_vec const *ctx) { return ctx->mem_; }
A_INTERN void *a_vec_at_(a_vec const *ctx, a_size idx)
{
return a_byte_(*, ctx->ptr_) + ctx->siz_ * idx;
}
#define A_VEC_AT_(T, ctx, idx) a_cast_s(T *, a_vec_at_(ctx, idx))
A_INTERN void *a_vec_at(a_vec const *ctx, a_size idx)
{
return idx < ctx->mem_ ? a_vec_at_(ctx, idx) : A_NULL;
}
#define A_VEC_AT(T, ctx, idx) a_cast_s(T *, a_vec_at(ctx, idx))
A_INTERN void *a_vec_idx(a_vec const *ctx, a_diff idx)
{
a_size const num = idx >= 0 ? a_size_c(idx) : a_size_c(idx) + ctx->num_;
return num < ctx->mem_ ? a_vec_at_(ctx, num) : A_NULL;
}
#define A_VEC_IDX(T, ctx, idx) a_cast_s(T *, a_vec_idx(ctx, idx))
A_INTERN void *a_vec_top_(a_vec const *ctx)
{
return a_byte_(*, ctx->ptr_) + ctx->siz_ * (ctx->num_ - 1);
}
#define A_VEC_TOP_(T, ctx) a_cast_s(T *, a_vec_top_(ctx))
A_INTERN void *a_vec_top(a_vec const *ctx)
{
return ctx->num_ ? a_vec_top_(ctx) : A_NULL;
}
#define A_VEC_TOP(T, ctx) a_cast_s(T *, a_vec_top(ctx))
A_INTERN void *a_vec_end_(a_vec const *ctx)
{
return a_byte_(*, ctx->ptr_) + ctx->siz_ * ctx->num_;
}
#define A_VEC_END_(T, ctx) a_cast_s(T *, a_vec_end_(ctx))
A_INTERN void *a_vec_end(a_vec const *ctx)
{
return ctx->ptr_ ? a_vec_end_(ctx) : ctx->ptr_;
}
#define A_VEC_END(T, ctx) a_cast_s(T *, a_vec_end(ctx))
#if defined(__cplusplus)
extern "C" {
#endif
A_EXTERN a_vec *a_vec_new(a_size size);
A_EXTERN void a_vec_die(a_vec *ctx, void (*dtor)(void *));
A_EXTERN void a_vec_ctor(a_vec *ctx, a_size size);
A_EXTERN void a_vec_dtor(a_vec *ctx, void (*dtor)(void *));
A_EXTERN int a_vec_copy(a_vec *ctx, a_vec const *obj, int (*dup)(void *, void const *));
A_EXTERN void a_vec_move(a_vec *ctx, a_vec *obj);
A_EXTERN void a_vec_edit(a_vec *ctx, a_size size, void (*dtor)(void *));
A_EXTERN int a_vec_make(a_vec *ctx, a_size num, void (*dtor)(void *));
A_EXTERN void a_vec_drop(a_vec *ctx, void (*dtor)(void *));
A_EXTERN void a_vec_swap(a_vec const *ctx, a_size lhs, a_size rhs);
A_EXTERN void a_vec_sort(a_vec const *ctx, int (*cmp)(void const *, void const *));
A_EXTERN void a_vec_sort_fore(a_vec const *ctx, int (*cmp)(void const *, void const *));
A_EXTERN void a_vec_sort_back(a_vec const *ctx, int (*cmp)(void const *, void const *));
A_EXTERN void *a_vec_push_sort(a_vec *ctx, void const *key, int (*cmp)(void const *, void const *));
#define A_VEC_PUSH_SORT(T, ctx, key, cmp) a_cast_s(T *, a_vec_push_sort(ctx, key, cmp))
A_EXTERN void *a_vec_search(a_vec const *ctx, void const *obj, int (*cmp)(void const *, void const *));
#define A_VEC_SEARCH(T, ctx, obj, cmp) a_cast_s(T *, a_vec_search(ctx, obj, cmp))
A_EXTERN void *a_vec_insert(a_vec *ctx, a_size idx);
#define A_VEC_INSERT(T, ctx, idx) a_cast_s(T *, a_vec_insert(ctx, idx))
A_EXTERN void *a_vec_remove(a_vec *ctx, a_size idx);
#define A_VEC_REMOVE(T, ctx, idx) a_cast_s(T *, a_vec_remove(ctx, idx))
A_EXTERN void *a_vec_push_fore(a_vec *ctx);
#define A_VEC_PUSH_FORE(T, ctx) a_cast_s(T *, a_vec_push_fore(ctx))
A_EXTERN void *a_vec_push_back(a_vec *ctx);
#define A_VEC_PUSH_BACK(T, ctx) a_cast_s(T *, a_vec_push_back(ctx))
A_EXTERN void *a_vec_pull_fore(a_vec *ctx);
#define A_VEC_PULL_FORE(T, ctx) a_cast_s(T *, a_vec_pull_fore(ctx))
A_EXTERN void *a_vec_pull_back(a_vec *ctx);
#define A_VEC_PULL_BACK(T, ctx) a_cast_s(T *, a_vec_pull_back(ctx))
#if defined(__cplusplus)
}
#endif
A_INTERN void *a_vec_push(a_vec *ctx) { return a_vec_push_back(ctx); }
#define A_VEC_PUSH(T, ctx) a_cast_s(T *, a_vec_push(ctx))
A_INTERN void *a_vec_pull(a_vec *ctx) { return a_vec_pull_back(ctx); }
#define A_VEC_PULL(T, ctx) a_cast_s(T *, a_vec_pull(ctx))
#define a_vec_forenum(i, ctx) a_forenum(a_size, i, (ctx)->num_)
#define a_vec_forenum_reverse(i, ctx) a_forenum_reverse(a_size, i, (ctx)->num_)
#define a_vec_foreach(T, P, it, ctx) a_forsafe(T, P, it, (ctx)->ptr_, (ctx)->num_)
#define a_vec_foreach_reverse(T, P, it, ctx) a_forsafe_reverse(T, P, it, (ctx)->ptr_, (ctx)->num_)
#endif