FORM 4.3
vector.h
Go to the documentation of this file.
1#ifndef VECTOR_H_
2#define VECTOR_H_
3
20/* #[ License : */
21/*
22 * Copyright (C) 1984-2022 J.A.M. Vermaseren
23 * When using this file you are requested to refer to the publication
24 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
25 * This is considered a matter of courtesy as the development was paid
26 * for by FOM the Dutch physics granting agency and we would like to
27 * be able to track its scientific use to convince FOM of its value
28 * for the community.
29 *
30 * This file is part of FORM.
31 *
32 * FORM is free software: you can redistribute it and/or modify it under the
33 * terms of the GNU General Public License as published by the Free Software
34 * Foundation, either version 3 of the License, or (at your option) any later
35 * version.
36 *
37 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
38 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
39 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
40 * details.
41 *
42 * You should have received a copy of the GNU General Public License along
43 * with FORM. If not, see <http://www.gnu.org/licenses/>.
44 */
45/* #] License : */
46/*
47 #[ Includes :
48*/
49
50#include <stddef.h>
51#include <string.h>
52#include "declare.h"
53
54/*
55 #] Includes :
56 #[ Vector :
57 #[ VectorStruct :
58*/
59
65#define VectorStruct(T) \
66 struct { \
67 T *ptr; \
68 size_t size; \
69 size_t capacity; \
70 }
71
72/*
73 #] VectorStruct :
74 #[ Vector :
75*/
76
84#define Vector(T, X) \
85 VectorStruct(T) X = { NULL, 0, 0 }
86
87/*
88 #] Vector :
89 #[ DeclareVector :
90*/
91
99#define DeclareVector(T, X) \
100 VectorStruct(T) X
101
102/*
103 #] DeclareVector :
104 #[ VectorInit :
105*/
106
113#define VectorInit(X) \
114 do { \
115 (X).ptr = NULL; \
116 (X).size = 0; \
117 (X).capacity = 0; \
118 } while (0)
119
120/*
121 #] VectorInit :
122 #[ VectorFree :
123*/
124
130#define VectorFree(X) \
131 do { \
132 M_free((X).ptr, "VectorFree:" #X); \
133 (X).ptr = NULL; \
134 (X).size = 0; \
135 (X).capacity = 0; \
136 } while (0)
137
138/*
139 #] VectorFree :
140 #[ VectorPtr :
141*/
142
150#define VectorPtr(X) \
151 ((X).ptr)
152
153/*
154 #] VectorPtr :
155 #[ VectorFront :
156*/
157
165#define VectorFront(X) \
166 ((X).ptr[0])
167
168/*
169 #] VectorFront :
170 #[ VectorBack :
171*/
172
180#define VectorBack(X) \
181 ((X).ptr[(X).size - 1])
182
183/*
184 #] VectorBack :
185 #[ VectorSize :
186*/
187
194#define VectorSize(X) \
195 ((X).size)
196
197/*
198 #] VectorSize :
199 #[ VectorCapacity :
200*/
201
208#define VectorCapacity(X) \
209 ((X).capacity)
210
211/*
212 #] VectorCapacity :
213 #[ VectorEmpty :
214*/
215
222#define VectorEmpty(X) \
223 ((X).size == 0)
224
225/*
226 #] VectorEmpty :
227 #[ VectorClear :
228*/
229
235#define VectorClear(X) \
236 do { (X).size = 0; } while (0)
237
238/*
239 #] VectorClear :
240 #[ VectorReserve :
241*/
242
249#define VectorReserve(X, newcapacity) \
250 do { \
251 size_t v_tmp_newcapacity_ = (newcapacity); \
252 if ( (X).capacity < v_tmp_newcapacity_ ) { \
253 void *v_tmp_newptr_; \
254 v_tmp_newcapacity_ = (v_tmp_newcapacity_ * 3) / 2; \
255 if ( v_tmp_newcapacity_ < 4 ) v_tmp_newcapacity_ = 4; \
256 v_tmp_newptr_ = Malloc1(sizeof((X).ptr[0]) * v_tmp_newcapacity_, "VectorReserve:" #X); \
257 if ( (X).ptr != NULL ) { \
258 memcpy(v_tmp_newptr_, (X).ptr, (X).size * sizeof((X).ptr[0])); \
259 M_free((X).ptr, "VectorReserve:" #X); \
260 } \
261 (X).ptr = v_tmp_newptr_; \
262 (X).capacity = v_tmp_newcapacity_; \
263 } \
264 } while (0)
265
266/*
267 #] VectorReserve :
268 #[ VectorPushBack :
269*/
270
277#define VectorPushBack(X, x) \
278 do { \
279 VectorReserve((X), (X).size + 1); \
280 (X).ptr[(X).size++] = (x); \
281 } while (0)
282
283/*
284 #] VectorPushBack :
285 #[ VectorPushBacks :
286*/
287
295#define VectorPushBacks(X, src, n) \
296 do { \
297 size_t v_tmp_n_ = (n); \
298 VectorReserve((X), (X).size + v_tmp_n_); \
299 memcpy((X).ptr + (X).size, (src), v_tmp_n_ * sizeof((X).ptr[0])); \
300 (X).size += v_tmp_n_; \
301 } while (0)
302
303/*
304 #] VectorPushBacks :
305 #[ VectorPopBack :
306*/
307
314#define VectorPopBack(X) \
315 do { (X).size --; } while (0)
316
317/*
318 #] VectorPopBack :
319 #[ VectorInsert :
320*/
321
330#define VectorInsert(X, index, x) \
331 do { \
332 size_t v_tmp_index_ = (index); \
333 VectorReserve((X), (X).size + 1); \
334 memmove((X).ptr + v_tmp_index_ + 1, (X).ptr + v_tmp_index_, ((X).size - v_tmp_index_) * sizeof((X).ptr[0])); \
335 (X).ptr[v_tmp_index_] = (x); \
336 (X).size++; \
337 } while (0)
338
339/*
340 #] VectorInsert :
341 #[ VectorInserts :
342*/
343
353#define VectorInserts(X, index, src, n) \
354 do { \
355 size_t v_tmp_index_ = (index), v_tmp_n_ = (n); \
356 VectorReserve((X), (X).size + v_tmp_n_); \
357 memmove((X).ptr + v_tmp_index_ + v_tmp_n_, (X).ptr + v_tmp_index_, ((X).size - v_tmp_index_) * sizeof((X).ptr[0])); \
358 memcpy((X).ptr + v_tmp_index_, (src), v_tmp_n_ * sizeof((X).ptr[0])); \
359 (X).size += v_tmp_n_; \
360 } while (0)
361
362/*
363 #] VectorInserts :
364 #[ VectorErase :
365*/
366
374#define VectorErase(X, index) \
375 do { \
376 size_t v_tmp_index_ = (index); \
377 memmove((X).ptr + v_tmp_index_, (X).ptr + v_tmp_index_ + 1, ((X).size - v_tmp_index_ - 1) * sizeof((X).ptr[0])); \
378 (X).size--; \
379 } while (0)
380
381/*
382 #] VectorErase :
383 #[ VectorErases :
384*/
385
394#define VectorErases(X, index, n) \
395 do { \
396 size_t v_tmp_index_ = (index), v_tmp_n_ = (n); \
397 memmove((X).ptr + v_tmp_index_, (X).ptr + v_tmp_index_ + v_tmp_n_, ((X).size - v_tmp_index_ - 1) * sizeof((X).ptr[0])); \
398 (X).size -= v_tmp_n_; \
399 } while (0)
400
401/*
402 #] VectorErases :
403 #] Vector :
404*/
405#endif /* VECTOR_H_ */