commit b9c673ffb02568211832f0767291afe0822114b8
parent 2df5ebc15b0eadaacbd274b46a282b7005d1a014
Author: Robert Russell <robertrussell.72001@gmail.com>
Date: Fri, 9 Sep 2022 11:03:56 -0700
Add null terminator option to vector
This will be needed for a future string/char vector type.
Diffstat:
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/inc/rcx/vector.h b/inc/rcx/vector.h
@@ -1,6 +1,7 @@
#pragma once
#include <errno.h>
+#include <stdbool.h>
#include <string.h>
#include "rcx/alloc.h"
@@ -19,6 +20,7 @@ typedef struct {
/* Defaults */
#define R_VECTOR_STATIC
#define R_VECTOR_METHOD(name, prefix) JOIN(JOIN(prefix,_),name)
+#define R_VECTOR_NULL_TERM false
#define R_VECTOR_MIN_CAP 8
#define R_VECTOR_HDR_TYPE r_vector_generic_hdr_
#define R_VECTOR_REALLOC r_erealloc
@@ -67,19 +69,22 @@ int R_VECTOR_METHOD(resize,##__VA_ARGS__)(T **v, usize cap) { \
} \
if (R_VECTOR_REALLOC(&h, sizeof *h + arrsize) < 0) \
return -1; \
- h->len = MIN(len, cap); \
+ h->len = MIN(len, cap - !!R_VECTOR_NULL_TERM); \
h->cap = cap; \
*v = (void *)(h + 1); \
+ if (R_VECTOR_NULL_TERM) \
+ memset(&(*v)[h->len], 0, sizeof (*v)[0]); \
} \
return 0; \
} \
int R_VECTOR_METHOD(reserve,##__VA_ARGS__)(T **v, usize n) { \
R_VECTOR_HDR_TYPE *h = *v ? R_VECTOR_HDR_(*v) : 0; \
- usize rem = h ? h->cap - h->len : 0; \
+ usize rem = h ? h->cap - h->len - !!R_VECTOR_NULL_TERM : 0; \
if (n > rem) { \
usize need = n - rem; \
- usize cap = h ? h->cap + MAX(h->cap, need) : need; \
- if (h && cap < h->cap) { /* Overflow? */ \
+ usize cap = h ? h->cap + MAX(h->cap, need) \
+ : need + !!R_VECTOR_NULL_TERM; \
+ if ((h && cap < h->cap) || (R_VECTOR_NULL_TERM && cap == 0)) { \
errno = ENOMEM; \
return -1; \
} \
@@ -98,8 +103,8 @@ int R_VECTOR_METHOD(insv,##__VA_ARGS__)(T **dst, usize i, T *src) { \
int R_VECTOR_METHOD(insn,##__VA_ARGS__)(T **dst, usize i, T *src, usize n) { \
if (R_VECTOR_METHOD(reserve,##__VA_ARGS__)(dst, n)) \
return -1; \
- memmove(&(*dst)[i+n], &(*dst)[i], \
- (R_VECTOR_HDR_(*dst)->len - i) * sizeof (*dst)[0]); \
+ usize m = R_VECTOR_HDR_(*dst)->len - i + !!R_VECTOR_NULL_TERM; \
+ memmove(&(*dst)[i+n], &(*dst)[i], m * sizeof (*dst)[0]); \
memcpy(&(*dst)[i], src, n * sizeof (*dst)[0]); \
R_VECTOR_HDR_(*dst)->len += n; \
return 0; \
@@ -117,9 +122,9 @@ int R_VECTOR_METHOD(catn,##__VA_ARGS__)(T **dst, T *src, usize n) { \
} \
T R_VECTOR_METHOD(del,##__VA_ARGS__)(T **v, usize i) { \
T e = (*v)[i]; \
- memmove(&(*v)[i], &(*v)[i+1], \
- (R_VECTOR_HDR_(*v)->len - i - 1) * sizeof (*v)[0]); \
- R_VECTOR_HDR_(*v)->len--; \
+ usize m = R_VECTOR_HDR_(*v)->len - i - 1 + !!R_VECTOR_NULL_TERM; \
+ memmove(&(*v)[i], &(*v)[i+1], m * sizeof (*v)[0]); \
+ R_VECTOR_HDR_(*v)->len -= 1; \
return e; \
} \
T R_VECTOR_METHOD(pop,##__VA_ARGS__)(T **v) { \