summaryrefslogtreecommitdiffstats
path: root/include/strvec.h
blob: 7ce1153be8fc8a46e8d7e36a2ec140b2e77a88b7 (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#pragma once

#include "dvec.h"
#include "allocator.h"

#include <stddef.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 {
	struct dvec vec;
};

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

struct strvec *strvec_alloc(size_t reserved,
	const 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);

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

static inline 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);
static inline 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);
int strvec_remove_str(struct strvec *strvec, const char *str,
	const struct allocator *allocator);
ssize_t strvec_find(struct strvec *strvec, size_t start, const char *str);

char *strvec_join(struct strvec *strvec, const char *sep,
	const struct allocator *allocator, int *rc);

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 const char **
strvec_stra(struct strvec *strvec)
{
	LIBSTRVEC_ABORT_ON_ARGS(!strvec && !strvec->vec.data);

	return (const char **)strvec->vec.data;
}

static inline const char **
strvec_at(struct strvec *strvec, size_t index)
{
	LIBSTRVEC_ABORT_ON_ARGS(!strvec);

	return dvec_at(&strvec->vec, index);
}

static inline size_t
strvec_len(struct strvec *strvec)
{
	LIBSTRVEC_ABORT_ON_ARGS(!strvec);

	return strvec->vec.len;
}

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);
}