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
|
#pragma once
#include "dvec.h"
#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 {
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);
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 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);
}
|