summaryrefslogtreecommitdiffstats
path: root/include/strvec.h
blob: 648487c2aaa43c220cf9cf4f5d11ee198be74321 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#pragma once

#include "allocator.h"

#include <stdbool.h>

#define STRVEC_ITER(strvec, p)     (p) = NULL; ((p) = strvec_iter_fwd((strvec), (p)));
#define STRVEC_ITER_BWD(strvec, p) (p) = NULL; ((p) = strvec_iter_bwd((strvec), (p)));

#ifdef LIBSTRVEC_ASSERT_ARGS
#include "stdlib.h"
#define LIBSTRVEC_ABORT_ON_ARGS(cond) do { if (cond) abort(); } while (0)
#else
#define LIBSTRVEC_ABORT_ON_ARGS(cond)
#endif

#ifdef LIBSTRVEC_ASSERT_ALLOC
#include "stdlib.h"
#define LIBSTRVEC_ABORT_ON_ALLOC(cond) do { if (cond) abort(); } while (0)
#else
#define LIBSTRVEC_ABORT_ON_ALLOC(cond)
#endif

struct strvec;

int strvec_init(struct strvec *strvec, size_t cap, struct allocator *allocator);
int strvec_deinit(struct strvec *strvec);

struct strvec *strvec_alloc(size_t reserved, struct allocator *allocator, int *rc);
int strvec_free(struct strvec *strvec);

int strvec_copy(struct strvec *dst, struct strvec *src,
	const struct allocator *allocator);
void strvec_move(struct strvec *dst, struct strvec *src);
void strvec_swap(struct strvec *dst, struct strvec *src);

void strvec_clear(struct strvec *strvec);
int strvec_reserve(struct strvec *strvec, size_t cap);
int strvec_shrink(struct strvec *strvec);

const char **strvec_stra(struct strvec *strvec);

const char **strvec_at(struct strvec *strvec, size_t index);
static inline const char *strvec_get(struct strvec *strvec, size_t index);
static inline const char *strvec_front(struct strvec *strvec);
static inline const char *strvec_back(struct strvec *strvec);
size_t strvec_len(struct strvec *strvec);
static inline bool strvec_empty(struct strvec *strvec);


int strvec_pushn(struct strvec *strvec, const char **str, size_t n);
static inline int strvec_push(struct strvec *strvec, const char *str);
const char **strvec_popn(struct strvec *strvec, size_t n);
static inline const char *strvec_pop(struct strvec *strvec);
void strvec_replace(struct strvec *strvec, size_t index, const char *str);
void strvec_remove(struct strvec *strvec, size_t index, size_t n);

const char **strvec_iter_fwd(const struct strvec *strvec, const char **p);
const char **strvec_iter_bwd(const struct strvec *strvec, const char **p);

static inline bool
strvec_empty(struct strvec *strvec)
{
	return strvec_len(strvec) == 0;
}

static inline const char *
strvec_get(struct strvec *strvec, size_t index)
{
	return *strvec_at(strvec, index);
}

static inline const char *
strvec_front(struct strvec *strvec)
{
	return *strvec_at(strvec, 0);
}

static inline const char *
strvec_back(struct strvec *strvec)
{
	LIBSTRVEC_ABORT_ON_ARGS(!strvec || strvec_empty(strvec));

	return *strvec_at(strvec, strvec_len(strvec) - 1);
}

static inline int
strvec_push(struct strvec *strvec, const char *str)
{
	return strvec_pushn(strvec, &str, 1);
}

static inline const char *
strvec_pop(struct strvec *strvec)
{
	return *strvec_popn(strvec, 1);
}

extern const size_t strvec_dsize;