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_ */