|
62 | 62 | * |
63 | 63 | * @warning 遍历过程中不能删除元素,否则会导致索引混乱 |
64 | 64 | */ |
65 | | -# define ek_vec_iterate(pos, v) for (pos = 0; pos < v.amount; pos++) |
| 65 | +# define ek_vec_iterate(pos, v) for (pos = 0; pos < (v).amount; pos++) |
66 | 66 |
|
67 | 67 | /** |
68 | 68 | * @brief 从指定索引开始遍历动态数组 |
|
72 | 72 | * |
73 | 73 | * @note 如果 index 超出范围,则从数组末尾开始(不会执行循环体) |
74 | 74 | */ |
75 | | -# define ek_vec_iterate_index(pos, index, v) for (pos = (index < v.amount) ? index : v.amount; pos < v.amount; pos++) |
| 75 | +# define ek_vec_iterate_index(pos, index, v) \ |
| 76 | + for (pos = ((index) < (v).amount) ? (index) : (v).amount; pos < (v).amount; pos++) |
76 | 77 |
|
77 | 78 | /** |
78 | 79 | * @brief 初始化动态数组 |
79 | 80 | * @param v 动态数组变量 |
80 | 81 | * |
81 | 82 | * @note 使用前必须调用此宏进行初始化 |
82 | 83 | */ |
83 | | -# define ek_vec_init(v) \ |
84 | | - do \ |
85 | | - { \ |
86 | | - v.items = NULL; \ |
87 | | - v.amount = 0; \ |
88 | | - v.cap = 0; \ |
| 84 | +# define ek_vec_init(v) \ |
| 85 | + do \ |
| 86 | + { \ |
| 87 | + (v).items = NULL; \ |
| 88 | + (v).amount = 0; \ |
| 89 | + (v).cap = 0; \ |
89 | 90 | } while (0) |
90 | 91 |
|
91 | 92 | /** |
|
95 | 96 | * @note 销毁后动态数组变量仍存在,但内容已清空 |
96 | 97 | * @note 如需重新使用,应重新调用 ek_vec_init |
97 | 98 | */ |
98 | | -# define ek_vec_destroy(v) \ |
99 | | - do \ |
100 | | - { \ |
101 | | - ek_free(v.items); \ |
102 | | - v.amount = 0; \ |
103 | | - v.cap = 0; \ |
| 99 | +# define ek_vec_destroy(v) \ |
| 100 | + do \ |
| 101 | + { \ |
| 102 | + ek_free((v).items); \ |
| 103 | + (v).amount = 0; \ |
| 104 | + (v).cap = 0; \ |
104 | 105 | } while (0) |
105 | 106 |
|
106 | 107 | /** |
|
111 | 112 | * @note 当容量不足时自动扩容 |
112 | 113 | * @note 扩容策略:小数组翻倍,大数组增加 1/2 |
113 | 114 | */ |
114 | | -# define ek_vec_append(v, val) \ |
115 | | - do \ |
116 | | - { \ |
117 | | - if (v.cap <= v.amount) \ |
118 | | - { \ |
119 | | - uint32_t _temp_for_cap_ex_ = \ |
120 | | - (v.cap < VEC_LARGE_THRESHOLD) ? (v.cap ? 2 * v.cap : 8) : (v.cap + v.cap / 2); \ |
121 | | - void *_temp_for_new_items_ = ek_realloc(v.items, _temp_for_cap_ex_ * sizeof(*v.items)); \ |
122 | | - if (_temp_for_new_items_ != NULL) \ |
123 | | - { \ |
124 | | - v.cap = _temp_for_cap_ex_; \ |
125 | | - v.items = _temp_for_new_items_; \ |
126 | | - } \ |
127 | | - else break; \ |
128 | | - } \ |
129 | | - v.items[v.amount++] = val; \ |
| 115 | +# define ek_vec_append(v, val) \ |
| 116 | + do \ |
| 117 | + { \ |
| 118 | + if ((v).cap <= (v).amount) \ |
| 119 | + { \ |
| 120 | + uint32_t _temp_for_cap_ex_ = \ |
| 121 | + ((v).cap < VEC_LARGE_THRESHOLD) ? ((v).cap ? 2 * (v).cap : 8) : ((v).cap + (v).cap / 2); \ |
| 122 | + void *_temp_for_new_items_ = ek_realloc((v).items, _temp_for_cap_ex_ * sizeof(*(v).items)); \ |
| 123 | + if (_temp_for_new_items_ != NULL) \ |
| 124 | + { \ |
| 125 | + (v).cap = _temp_for_cap_ex_; \ |
| 126 | + (v).items = _temp_for_new_items_; \ |
| 127 | + } \ |
| 128 | + else break; \ |
| 129 | + } \ |
| 130 | + (v).items[(v).amount++] = (val); \ |
130 | 131 | } while (0) |
131 | 132 |
|
132 | 133 | /** |
|
137 | 138 | * @note 移除后,后续元素会向前移动填补空位 |
138 | 139 | * @note 如果索引超出范围,则不执行任何操作 |
139 | 140 | */ |
140 | | -# define ek_vec_remove(v, index) \ |
141 | | - do \ |
142 | | - { \ |
143 | | - if (index < v.amount) \ |
144 | | - { \ |
145 | | - for (uint32_t _temp_for_iter_v_ = index; _temp_for_iter_v_ < v.amount - 1; _temp_for_iter_v_++) \ |
146 | | - { \ |
147 | | - v.items[_temp_for_iter_v_] = v.items[_temp_for_iter_v_ + 1]; \ |
148 | | - } \ |
149 | | - v.amount--; \ |
150 | | - } \ |
| 141 | +# define ek_vec_remove(v, index) \ |
| 142 | + do \ |
| 143 | + { \ |
| 144 | + if ((index) < (v).amount) \ |
| 145 | + { \ |
| 146 | + for (uint32_t _temp_for_iter_v_ = (index); _temp_for_iter_v_ < (v).amount - 1; _temp_for_iter_v_++) \ |
| 147 | + { \ |
| 148 | + (v).items[_temp_for_iter_v_] = (v).items[_temp_for_iter_v_ + 1]; \ |
| 149 | + } \ |
| 150 | + (v).amount--; \ |
| 151 | + } \ |
151 | 152 | } while (0) |
152 | 153 |
|
153 | 154 | /** |
|
159 | 160 | * @note 时间复杂度:O(1) |
160 | 161 | * @warning 会破坏数组中元素的原始顺序,仅适用于对顺序不敏感的场景 |
161 | 162 | */ |
162 | | -# define ek_vec_remove_unorder(v, index) \ |
163 | | - do \ |
164 | | - { \ |
165 | | - if (index < v.amount) \ |
166 | | - { \ |
167 | | - v.items[index] = v.items[v.amount - 1]; \ |
168 | | - v.amount--; \ |
169 | | - } \ |
| 163 | +# define ek_vec_remove_unorder(v, index) \ |
| 164 | + do \ |
| 165 | + { \ |
| 166 | + if ((index) < (v).amount) \ |
| 167 | + { \ |
| 168 | + (v).items[(index)] = (v).items[(v).amount - 1]; \ |
| 169 | + (v).amount--; \ |
| 170 | + } \ |
170 | 171 | } while (0) |
171 | 172 |
|
172 | 173 | /** |
|
179 | 180 | # define ek_vec_clear(v) \ |
180 | 181 | do \ |
181 | 182 | { \ |
182 | | - v.amount = 0; \ |
| 183 | + (v).amount = 0; \ |
183 | 184 | } while (0) |
184 | 185 |
|
185 | 186 | /** |
|
189 | 190 | * @note 将容量缩减为当前元素数量,释放多余内存,如果元素数目为0,则会释放items的所有内存 |
190 | 191 | * @note 如果 realloc 失败,则保持原状态不变 |
191 | 192 | */ |
192 | | -# define ek_vec_shrink(v) \ |
193 | | - do \ |
194 | | - { \ |
195 | | - if (v.amount) \ |
196 | | - { \ |
197 | | - void *_temp_for_new_items_ = ek_realloc(v.items, v.amount * sizeof(*v.items)); \ |
198 | | - if (_temp_for_new_items_) \ |
199 | | - { \ |
200 | | - v.items = _temp_for_new_items_; \ |
201 | | - v.cap = v.amount; \ |
202 | | - } \ |
203 | | - } \ |
204 | | - else if (v.items) \ |
205 | | - { \ |
206 | | - ek_free(v.items); \ |
207 | | - v.items = NULL; \ |
208 | | - v.cap = 0; \ |
209 | | - } \ |
| 193 | +# define ek_vec_shrink(v) \ |
| 194 | + do \ |
| 195 | + { \ |
| 196 | + if ((v).amount) \ |
| 197 | + { \ |
| 198 | + void *_temp_for_new_items_ = ek_realloc((v).items, (v).amount * sizeof(*(v).items)); \ |
| 199 | + if (_temp_for_new_items_) \ |
| 200 | + { \ |
| 201 | + (v).items = _temp_for_new_items_; \ |
| 202 | + (v).cap = (v).amount; \ |
| 203 | + } \ |
| 204 | + } \ |
| 205 | + else if ((v).items) \ |
| 206 | + { \ |
| 207 | + ek_free((v).items); \ |
| 208 | + (v).items = NULL; \ |
| 209 | + (v).cap = 0; \ |
| 210 | + } \ |
210 | 211 | } while (0) |
211 | 212 |
|
212 | 213 | #endif /* EK_VEC_ENABLE */ |
|
0 commit comments