update options for pip installation in README.md
[liba.git] / src / buf.c
blob3e9e6206d3b71f19dbe97d02563709f1862a03d5
1 #include "a/buf.h"
2 #include <stdlib.h>
4 #undef a_buf_at
5 #undef a_buf_at_
6 #undef a_buf_idx
7 #undef a_buf_ptr
8 #undef a_buf_end
9 #undef a_buf_top
10 #undef a_buf_top_
11 #undef a_buf_push
12 #undef a_buf_pull
13 #undef a_buf_search
14 #undef a_buf_insert
15 #undef a_buf_remove
16 #undef a_buf_push_fore
17 #undef a_buf_push_back
18 #undef a_buf_pull_fore
19 #undef a_buf_pull_back
21 static A_INLINE void *a_buf_inc_(a_buf *ctx)
23 return (a_byte *)ctx->ptr_ + ctx->siz_ * ctx->num_++;
26 static A_INLINE void *a_buf_dec_(a_buf *ctx)
28 return (a_byte *)ctx->ptr_ + ctx->siz_ * --ctx->num_;
31 static void a_buf_drop_(a_buf *ctx, a_size bot, void (*dtor)(void *))
33 if (dtor)
35 while (ctx->num_ > bot) { dtor(a_buf_dec_(ctx)); }
37 ctx->num_ = bot;
40 void a_buf_ctor(a_buf *ctx, void *ptr, a_size siz, a_size num)
42 ctx->ptr_ = ptr;
43 ctx->siz_ = siz;
44 ctx->mem_ = num;
45 ctx->num_ = 0;
48 void a_buf_dtor(a_buf *ctx, void (*dtor)(void *))
50 if (ctx->ptr_)
52 a_buf_drop_(ctx, 0, dtor);
53 ctx->ptr_ = A_NULL;
55 ctx->siz_ = 0;
56 ctx->mem_ = 0;
59 void a_buf_move(a_buf *ctx, a_buf *obj)
61 a_copy(ctx, obj, sizeof(*obj));
62 a_zero(obj, sizeof(*obj));
65 void a_buf_drop(a_buf *ctx, void (*dtor)(void *))
67 a_buf_drop_(ctx, 0, dtor);
70 void a_buf_swap(a_buf const *ctx, a_size lhs, a_size rhs)
72 a_size const num = ctx->num_ - 1;
73 lhs = lhs < ctx->num_ ? lhs : num;
74 rhs = rhs < ctx->num_ ? rhs : num;
75 if (lhs != rhs)
77 a_swap((a_byte *)ctx->ptr_ + lhs * ctx->siz_,
78 (a_byte *)ctx->ptr_ + rhs * ctx->siz_,
79 ctx->siz_);
83 void a_buf_sort(a_buf const *ctx, int (*cmp)(void const *, void const *))
85 qsort(ctx->ptr_, ctx->num_, ctx->siz_, cmp);
88 void a_buf_sort_fore(a_buf const *ctx, int (*cmp)(void const *, void const *))
90 if (ctx->num_ > 1)
92 a_byte *ptr = (a_byte *)ctx->ptr_;
93 a_byte *const end = (a_byte *)ctx->ptr_ + ctx->siz_ * ctx->num_ - ctx->siz_;
94 do {
95 a_byte *const cur = ptr + ctx->siz_;
96 if (cmp(ptr, cur) > 0)
98 a_swap(cur, ptr, ctx->siz_);
100 else { break; }
101 ptr = cur;
102 } while (ptr != end);
106 void a_buf_sort_back(a_buf const *ctx, int (*cmp)(void const *, void const *))
108 if (ctx->num_ > 1)
110 a_byte *ptr = (a_byte *)ctx->ptr_ + ctx->siz_ * ctx->num_ - ctx->siz_;
111 do {
112 a_byte *const cur = ptr - ctx->siz_;
113 if (cmp(cur, ptr) > 0)
115 a_swap(cur, ptr, ctx->siz_);
117 else { break; }
118 ptr = cur;
119 } while (ptr != ctx->ptr_);
123 void *a_buf_search(a_buf const *ctx, void const *obj, int (*cmp)(void const *, void const *))
125 return bsearch(obj, ctx->ptr_, ctx->num_, ctx->siz_, cmp);
128 void *a_buf_insert(a_buf *ctx, a_size idx)
130 if (a_likely(ctx->num_ < ctx->mem_))
132 if (idx < ctx->num_)
134 a_byte *const src = (a_byte *)ctx->ptr_ + ctx->siz_ * (idx + 0);
135 a_byte *const dst = (a_byte *)ctx->ptr_ + ctx->siz_ * (idx + 1);
136 a_move(dst, src, (ctx->num_ - idx) * ctx->siz_);
137 ++ctx->num_;
138 return src;
140 return a_buf_inc_(ctx);
142 return A_NULL;
145 void *a_buf_push_fore(a_buf *ctx) { return a_buf_insert(ctx, 0); }
147 void *a_buf_push_back(a_buf *ctx)
149 return a_likely(ctx->num_ < ctx->mem_) ? a_buf_inc_(ctx) : A_NULL;
152 void *a_buf_remove(a_buf *ctx, a_size idx)
154 a_size const num = ctx->num_ - 1;
155 if (ctx->num_ && idx < num)
157 a_byte *const ptr = (a_byte *)ctx->ptr_ + ctx->siz_ * num;
158 a_byte *const dst = (a_byte *)ctx->ptr_ + ctx->siz_ * (idx + 0);
159 a_byte *const src = (a_byte *)ctx->ptr_ + ctx->siz_ * (idx + 1);
160 a_swap(dst, src, (a_size)(ptr - dst));
161 --ctx->num_;
162 return ptr;
164 return a_likely(ctx->num_) ? a_buf_dec_(ctx) : A_NULL;
167 void *a_buf_pull_fore(a_buf *ctx) { return a_buf_remove(ctx, 0); }
169 void *a_buf_pull_back(a_buf *ctx)
171 return a_likely(ctx->num_) ? a_buf_dec_(ctx) : A_NULL;