GDBserver

vec.h
Go to the documentation of this file.
1 /* Vector API for GDB.
2 Copyright (C) 2004-2018 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #if !defined (GDB_VEC_H)
21 #define GDB_VEC_H
22
23 #include "diagnostics.h"
24
25 /* clang has a bug that makes it warn (-Wunused-function) about unused functions
26 that are the result of the DEF_VEC_* macro expansion. See:
27
28 https://bugs.llvm.org/show_bug.cgi?id=22712
29
30 We specifically ignore this warning for the vec functions when the compiler
31 is clang. */
32 #ifdef __clang__
33 # define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
34 DIAGNOSTIC_IGNORE_UNUSED_FUNCTION
35 #else
36 # define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION
37 #endif
38
39 /* The macros here implement a set of templated vector types and
40 associated interfaces. These templates are implemented with
41 macros, as we're not in C++ land. The interface functions are
42 typesafe and use static inline functions, sometimes backed by
43 out-of-line generic functions.
44
45 Because of the different behavior of structure objects, scalar
46 objects and of pointers, there are three flavors, one for each of
47 these variants. Both the structure object and pointer variants
48 pass pointers to objects around -- in the former case the pointers
49 are stored into the vector and in the latter case the pointers are
50 dereferenced and the objects copied into the vector. The scalar
51 object variant is suitable for int-like objects, and the vector
52 elements are returned by value.
53
54 There are both 'index' and 'iterate' accessors. The iterator
55 returns a boolean iteration condition and updates the iteration
56 variable passed by reference. Because the iterator will be
57 inlined, the address-of can be optimized away.
58
59 The vectors are implemented using the trailing array idiom, thus
60 they are not resizeable without changing the address of the vector
61 object itself. This means you cannot have variables or fields of
62 vector type -- always use a pointer to a vector. The one exception
63 is the final field of a structure, which could be a vector type.
64 You will have to use the embedded_size & embedded_init calls to
65 create such objects, and they will probably not be resizeable (so
66 don't use the 'safe' allocation variants). The trailing array
67 idiom is used (rather than a pointer to an array of data), because,
68 if we allow NULL to also represent an empty vector, empty vectors
69 occupy minimal space in the structure containing them.
70
71 Each operation that increases the number of active elements is
72 available in 'quick' and 'safe' variants. The former presumes that
73 there is sufficient allocated space for the operation to succeed
74 (it dies if there is not). The latter will reallocate the
75 vector, if needed. Reallocation causes an exponential increase in
76 vector size. If you know you will be adding N elements, it would
77 be more efficient to use the reserve operation before adding the
78 elements with the 'quick' operation. This will ensure there are at
79 least as many elements as you ask for, it will exponentially
80 increase if there are too few spare slots. If you want reserve a
81 specific number of slots, but do not want the exponential increase
82 (for instance, you know this is the last allocation), use a
83 negative number for reservation. You can also create a vector of a
84 specific size from the get go.
85
86 You should prefer the push and pop operations, as they append and
87 remove from the end of the vector. If you need to remove several
88 items in one go, use the truncate operation. The insert and remove
89 operations allow you to change elements in the middle of the
90 vector. There are two remove operations, one which preserves the
91 element ordering 'ordered_remove', and one which does not
92 'unordered_remove'. The latter function copies the end element
93 into the removed slot, rather than invoke a memmove operation. The
94 'lower_bound' function will determine where to place an item in the
95 array using insert that will maintain sorted order.
96
97 If you need to directly manipulate a vector, then the 'address'
98 accessor will return the address of the start of the vector. Also
99 the 'space' predicate will tell you whether there is spare capacity
100 in the vector. You will not normally need to use these two functions.
101
102 Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro.
103 Variables of vector type are declared using a VEC(TYPEDEF) macro.
104 The characters O, P and I indicate whether TYPEDEF is a pointer
105 (P), object (O) or integral (I) type. Be careful to pick the
106 correct one, as you'll get an awkward and inefficient API if you
107 use the wrong one. There is a check, which results in a
108 compile-time warning, for the P and I versions, but there is no
109 check for the O versions, as that is not possible in plain C.
110
111 An example of their use would be,
112
113 DEF_VEC_P(tree); // non-managed tree vector.
114
115 struct my_struct {
116 VEC(tree) *v; // A (pointer to) a vector of tree pointers.
117 };
118
119 struct my_struct *s;
120
121 if (VEC_length(tree, s->v)) { we have some contents }
122 VEC_safe_push(tree, s->v, decl); // append some decl onto the end
123 for (ix = 0; VEC_iterate(tree, s->v, ix, elt); ix++)
124 { do something with elt }
125
126 */
127
128 /* Macros to invoke API calls. A single macro works for both pointer
129 and object vectors, but the argument and return types might well be
130 different. In each macro, T is the typedef of the vector elements.
131 Some of these macros pass the vector, V, by reference (by taking
132 its address), this is noted in the descriptions. */
133
134 /* Length of vector
135 unsigned VEC_T_length(const VEC(T) *v);
136
137 Return the number of active elements in V. V can be NULL, in which
138 case zero is returned. */
139
140 #define VEC_length(T,V) (VEC_OP(T,length)(V))
141
142
143 /* Check if vector is empty
144 int VEC_T_empty(const VEC(T) *v);
145
146 Return nonzero if V is an empty vector (or V is NULL), zero otherwise. */
147
148 #define VEC_empty(T,V) (VEC_length (T,V) == 0)
149
150
151 /* Get the final element of the vector.
152 T VEC_T_last(VEC(T) *v); // Integer
153 T VEC_T_last(VEC(T) *v); // Pointer
154 T *VEC_T_last(VEC(T) *v); // Object
155
156 Return the final element. V must not be empty. */
157
158 #define VEC_last(T,V) (VEC_OP(T,last)(V VEC_ASSERT_INFO))
159
160 /* Index into vector
161 T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
162 T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
163 T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
164
165 Return the IX'th element. If IX must be in the domain of V. */
166
167 #define VEC_index(T,V,I) (VEC_OP(T,index)(V,I VEC_ASSERT_INFO))
168
169 /* Iterate over vector
170 int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
171 int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
172 int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
173
174 Return iteration condition and update PTR to point to the IX'th
175 element. At the end of iteration, sets PTR to NULL. Use this to
176 iterate over the elements of a vector as follows,
177
178 for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
179 continue; */
180
181 #define VEC_iterate(T,V,I,P) (VEC_OP(T,iterate)(V,I,&(P)))
182
183 /* Allocate new vector.
184 VEC(T,A) *VEC_T_alloc(int reserve);
185
186 Allocate a new vector with space for RESERVE objects. If RESERVE
187 is zero, NO vector is created. */
188
189 #define VEC_alloc(T,N) (VEC_OP(T,alloc)(N))
190
191 /* Free a vector.
192 void VEC_T_free(VEC(T,A) *&);
193
194 Free a vector and set it to NULL. */
195
196 #define VEC_free(T,V) (VEC_OP(T,free)(&V))
197
198 /* A cleanup function for a vector.
199 void VEC_T_cleanup(void *);
200
201 Clean up a vector. */
202
203 #define VEC_cleanup(T) (VEC_OP(T,cleanup))
204
205 /* Use these to determine the required size and initialization of a
206 vector embedded within another structure (as the final member).
207
208 size_t VEC_T_embedded_size(int reserve);
209 void VEC_T_embedded_init(VEC(T) *v, int reserve);
210
211 These allow the caller to perform the memory allocation. */
212
213 #define VEC_embedded_size(T,N) (VEC_OP(T,embedded_size)(N))
214 #define VEC_embedded_init(T,O,N) (VEC_OP(T,embedded_init)(VEC_BASE(O),N))
215
216 /* Copy a vector.
217 VEC(T,A) *VEC_T_copy(VEC(T) *);
218
219 Copy the live elements of a vector into a new vector. The new and
220 old vectors need not be allocated by the same mechanism. */
221
222 #define VEC_copy(T,V) (VEC_OP(T,copy)(V))
223
224 /* Merge two vectors.
225 VEC(T,A) *VEC_T_merge(VEC(T) *, VEC(T) *);
226
227 Copy the live elements of both vectors into a new vector. The new
228 and old vectors need not be allocated by the same mechanism. */
229 #define VEC_merge(T,V1,V2) (VEC_OP(T,merge)(V1, V2))
230
231 /* Determine if a vector has additional capacity.
232
233 int VEC_T_space (VEC(T) *v,int reserve)
234
235 If V has space for RESERVE additional entries, return nonzero. You
236 usually only need to use this if you are doing your own vector
237 reallocation, for instance on an embedded vector. This returns
238 nonzero in exactly the same circumstances that VEC_T_reserve
239 will. */
240
241 #define VEC_space(T,V,R) (VEC_OP(T,space)(V,R VEC_ASSERT_INFO))
242
243 /* Reserve space.
244 int VEC_T_reserve(VEC(T,A) *&v, int reserve);
245
246 Ensure that V has at least abs(RESERVE) slots available. The
247 signedness of RESERVE determines the reallocation behavior. A
248 negative value will not create additional headroom beyond that
249 requested. A positive value will create additional headroom. Note
250 this can cause V to be reallocated. Returns nonzero iff
251 reallocation actually occurred. */
252
253 #define VEC_reserve(T,V,R) (VEC_OP(T,reserve)(&(V),R VEC_ASSERT_INFO))
254
255 /* Push object with no reallocation
256 T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
257 T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
258 T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
259
260 Push a new element onto the end, returns a pointer to the slot
261 filled in. For object vectors, the new value can be NULL, in which
262 case NO initialization is performed. There must
263 be sufficient space in the vector. */
264
265 #define VEC_quick_push(T,V,O) (VEC_OP(T,quick_push)(V,O VEC_ASSERT_INFO))
266
267 /* Push object with reallocation
268 T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Integer
269 T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Pointer
270 T *VEC_T_safe_push (VEC(T,A) *&v, T *obj); // Object
271
272 Push a new element onto the end, returns a pointer to the slot
273 filled in. For object vectors, the new value can be NULL, in which
274 case NO initialization is performed. Reallocates V, if needed. */
275
276 #define VEC_safe_push(T,V,O) (VEC_OP(T,safe_push)(&(V),O VEC_ASSERT_INFO))
277
278 /* Pop element off end
279 T VEC_T_pop (VEC(T) *v); // Integer
280 T VEC_T_pop (VEC(T) *v); // Pointer
281 void VEC_T_pop (VEC(T) *v); // Object
282
283 Pop the last element off the end. Returns the element popped, for
284 pointer vectors. */
285
286 #define VEC_pop(T,V) (VEC_OP(T,pop)(V VEC_ASSERT_INFO))
287
288 /* Truncate to specific length
289 void VEC_T_truncate (VEC(T) *v, unsigned len);
290
291 Set the length as specified. The new length must be less than or
292 equal to the current length. This is an O(1) operation. */
293
294 #define VEC_truncate(T,V,I) \
295 (VEC_OP(T,truncate)(V,I VEC_ASSERT_INFO))
296
297 /* Grow to a specific length.
298 void VEC_T_safe_grow (VEC(T,A) *&v, int len);
299
300 Grow the vector to a specific length. The LEN must be as
301 long or longer than the current length. The new elements are
302 uninitialized. */
303
304 #define VEC_safe_grow(T,V,I) \
305 (VEC_OP(T,safe_grow)(&(V),I VEC_ASSERT_INFO))
306
307 /* Replace element
308 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
309 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
310 T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
311
312 Replace the IXth element of V with a new value, VAL. For pointer
313 vectors returns the original value. For object vectors returns a
314 pointer to the new value. For object vectors the new value can be
315 NULL, in which case no overwriting of the slot is actually
316 performed. */
317
318 #define VEC_replace(T,V,I,O) (VEC_OP(T,replace)(V,I,O VEC_ASSERT_INFO))
319
320 /* Insert object with no reallocation
321 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
322 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
323 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
324
325 Insert an element, VAL, at the IXth position of V. Return a pointer
326 to the slot created. For vectors of object, the new value can be
327 NULL, in which case no initialization of the inserted slot takes
328 place. There must be sufficient space. */
329
330 #define VEC_quick_insert(T,V,I,O) \
331 (VEC_OP(T,quick_insert)(V,I,O VEC_ASSERT_INFO))
332
333 /* Insert object with reallocation
334 T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
335 T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
336 T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
337
338 Insert an element, VAL, at the IXth position of V. Return a pointer
339 to the slot created. For vectors of object, the new value can be
340 NULL, in which case no initialization of the inserted slot takes
341 place. Reallocate V, if necessary. */
342
343 #define VEC_safe_insert(T,V,I,O) \
344 (VEC_OP(T,safe_insert)(&(V),I,O VEC_ASSERT_INFO))
345
346 /* Remove element retaining order
347 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
348 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
349 void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
350
351 Remove an element from the IXth position of V. Ordering of
352 remaining elements is preserved. For pointer vectors returns the
353 removed object. This is an O(N) operation due to a memmove. */
354
355 #define VEC_ordered_remove(T,V,I) \
356 (VEC_OP(T,ordered_remove)(V,I VEC_ASSERT_INFO))
357
358 /* Remove element destroying order
359 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
360 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
361 void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
362
363 Remove an element from the IXth position of V. Ordering of
364 remaining elements is destroyed. For pointer vectors returns the
365 removed object. This is an O(1) operation. */
366
367 #define VEC_unordered_remove(T,V,I) \
368 (VEC_OP(T,unordered_remove)(V,I VEC_ASSERT_INFO))
369
370 /* Remove a block of elements
371 void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
372
373 Remove LEN elements starting at the IXth. Ordering is retained.
374 This is an O(N) operation due to memmove. */
375
376 #define VEC_block_remove(T,V,I,L) \
377 (VEC_OP(T,block_remove)(V,I,L VEC_ASSERT_INFO))
378
379 /* Get the address of the array of elements
380 T *VEC_T_address (VEC(T) v)
381
382 If you need to directly manipulate the array (for instance, you
383 want to feed it to qsort), use this accessor. */
384
385 #define VEC_address(T,V) (VEC_OP(T,address)(V))
386
387 /* Find the first index in the vector not less than the object.
388 unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
389 int (*lessthan) (const T, const T)); // Integer
390 unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
391 int (*lessthan) (const T, const T)); // Pointer
392 unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
393 int (*lessthan) (const T*, const T*)); // Object
394
395 Find the first position in which VAL could be inserted without
396 changing the ordering of V. LESSTHAN is a function that returns
397 true if the first argument is strictly less than the second. */
398
399 #define VEC_lower_bound(T,V,O,LT) \
400 (VEC_OP(T,lower_bound)(V,O,LT VEC_ASSERT_INFO))
401
402 /* Reallocate an array of elements with prefix. */
403 extern void *vec_p_reserve (void *, int);
404 extern void *vec_o_reserve (void *, int, size_t, size_t);
405 #define vec_free_(V) xfree (V)
406
407 #define VEC_ASSERT_INFO ,__FILE__,__LINE__
408 #define VEC_ASSERT_DECL ,const char *file_,unsigned line_
409 #define VEC_ASSERT_PASS ,file_,line_
410 #define vec_assert(expr, op) \
411 ((void)((expr) ? 0 : (gdb_assert_fail (op, file_, line_, \
412 FUNCTION_NAME), 0)))
413
414 #define VEC(T) VEC_##T
415 #define VEC_OP(T,OP) VEC_##T##_##OP
416
417 #define VEC_T(T) \
418 typedef struct VEC(T) \
419 { \
420 unsigned num; \
421 unsigned alloc; \
422 T vec[1]; \
423 } VEC(T)
424
425 /* Vector of integer-like object. */
426 #define DEF_VEC_I(T) \
427 DIAGNOSTIC_PUSH \
428 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
429 static inline void VEC_OP (T,must_be_integral_type) (void) \
430 { \
431 (void)~(T)0; \
432 } \
433 \
434 VEC_T(T); \
435 DEF_VEC_FUNC_P(T) \
436 DEF_VEC_ALLOC_FUNC_I(T) \
437 DIAGNOSTIC_POP \
438 struct vec_swallow_trailing_semi
439
440 /* Vector of pointer to object. */
441 #define DEF_VEC_P(T) \
442 DIAGNOSTIC_PUSH \
443 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
444 static inline void VEC_OP (T,must_be_pointer_type) (void) \
445 { \
446 (void)((T)1 == (void *)1); \
447 } \
448 \
449 VEC_T(T); \
450 DEF_VEC_FUNC_P(T) \
451 DEF_VEC_ALLOC_FUNC_P(T) \
452 DIAGNOSTIC_POP \
453 struct vec_swallow_trailing_semi
454
455 /* Vector of object. */
456 #define DEF_VEC_O(T) \
457 DIAGNOSTIC_PUSH \
458 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
459 VEC_T(T); \
460 DEF_VEC_FUNC_O(T) \
461 DEF_VEC_ALLOC_FUNC_O(T) \
462 DIAGNOSTIC_POP \
463 struct vec_swallow_trailing_semi
464
465 /* Avoid offsetof (or its usual C implementation) as it triggers
466 -Winvalid-offsetof warnings with enum_flags types with G++ <= 4.4,
467 even though those types are memcpyable. This requires allocating a
468 dummy local VEC in all routines that use this, but that has the
469 advantage that it only works if T is default constructible, which
470 is exactly a check we want, to keep C compatibility. */
471 #define vec_offset(T, VPTR) ((size_t) ((char *) &(VPTR)->vec - (char *) VPTR))
472
473 #define DEF_VEC_ALLOC_FUNC_I(T) \
474 static inline VEC(T) *VEC_OP (T,alloc) \
475 (int alloc_) \
476 { \
477 VEC(T) dummy; \
478 \
479 /* We must request exact size allocation, hence the negation. */ \
480 return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
481 vec_offset (T, &dummy), sizeof (T)); \
482 } \
483 \
484 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
485 { \
486 size_t len_ = vec_ ? vec_->num : 0; \
487 VEC (T) *new_vec_ = NULL; \
488 \
489 if (len_) \
490 { \
491 VEC(T) dummy; \
492 \
493 /* We must request exact size allocation, hence the negation. */ \
494 new_vec_ = (VEC (T) *) \
495 vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
496 \
497 new_vec_->num = len_; \
498 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
499 } \
500 return new_vec_; \
501 } \
502 \
503 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
504 { \
505 if (vec1_ && vec2_) \
506 { \
507 VEC(T) dummy; \
508 size_t len_ = vec1_->num + vec2_->num; \
509 VEC (T) *new_vec_ = NULL; \
510 \
511 /* We must request exact size allocation, hence the negation. */ \
512 new_vec_ = (VEC (T) *) \
513 vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
514 \
515 new_vec_->num = len_; \
516 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
517 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
518 sizeof (T) * vec2_->num); \
519 \
520 return new_vec_; \
521 } \
522 else \
523 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
524 } \
525 \
526 static inline void VEC_OP (T,free) \
527 (VEC(T) **vec_) \
528 { \
529 if (*vec_) \
530 vec_free_ (*vec_); \
531 *vec_ = NULL; \
532 } \
533 \
534 static inline void VEC_OP (T,cleanup) \
535 (void *arg_) \
536 { \
537 VEC(T) **vec_ = (VEC(T) **) arg_; \
538 if (*vec_) \
539 vec_free_ (*vec_); \
540 *vec_ = NULL; \
541 } \
542 \
543 static inline int VEC_OP (T,reserve) \
544 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
545 { \
546 VEC(T) dummy; \
547 int extend = !VEC_OP (T,space) \
548 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
549 \
550 if (extend) \
551 *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_, \
552 vec_offset (T, &dummy), sizeof (T)); \
553 \
554 return extend; \
555 } \
556 \
557 static inline void VEC_OP (T,safe_grow) \
558 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
559 { \
560 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
561 "safe_grow"); \
562 VEC_OP (T,reserve) (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ \
563 VEC_ASSERT_PASS); \
564 (*vec_)->num = size_; \
565 } \
566 \
567 static inline T *VEC_OP (T,safe_push) \
568 (VEC(T) **vec_, const T obj_ VEC_ASSERT_DECL) \
569 { \
570 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
571 \
572 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
573 } \
574 \
575 static inline T *VEC_OP (T,safe_insert) \
576 (VEC(T) **vec_, unsigned ix_, const T obj_ VEC_ASSERT_DECL) \
577 { \
578 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
579 \
580 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
581 }
582
583 #define DEF_VEC_FUNC_P(T) \
584 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
585 { \
586 return vec_ ? vec_->num : 0; \
587 } \
588 \
589 static inline T VEC_OP (T,last) \
590 (const VEC(T) *vec_ VEC_ASSERT_DECL) \
591 { \
592 vec_assert (vec_ && vec_->num, "last"); \
593 \
594 return vec_->vec[vec_->num - 1]; \
595 } \
596 \
597 static inline T VEC_OP (T,index) \
598 (const VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
599 { \
600 vec_assert (vec_ && ix_ < vec_->num, "index"); \
601 \
602 return vec_->vec[ix_]; \
603 } \
604 \
605 static inline int VEC_OP (T,iterate) \
606 (const VEC(T) *vec_, unsigned ix_, T *ptr) \
607 { \
608 if (vec_ && ix_ < vec_->num) \
609 { \
610 *ptr = vec_->vec[ix_]; \
611 return 1; \
612 } \
613 else \
614 { \
615 *ptr = (T) 0; \
616 return 0; \
617 } \
618 } \
619 \
620 static inline size_t VEC_OP (T,embedded_size) \
621 (int alloc_) \
622 { \
623 VEC(T) dummy; \
624 \
625 return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
626 } \
627 \
628 static inline void VEC_OP (T,embedded_init) \
629 (VEC(T) *vec_, int alloc_) \
630 { \
631 vec_->num = 0; \
632 vec_->alloc = alloc_; \
633 } \
634 \
635 static inline int VEC_OP (T,space) \
636 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
637 { \
638 vec_assert (alloc_ >= 0, "space"); \
639 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
640 } \
641 \
642 static inline T *VEC_OP (T,quick_push) \
643 (VEC(T) *vec_, T obj_ VEC_ASSERT_DECL) \
644 { \
645 T *slot_; \
646 \
647 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
648 slot_ = &vec_->vec[vec_->num++]; \
649 *slot_ = obj_; \
650 \
651 return slot_; \
652 } \
653 \
654 static inline T VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
655 { \
656 T obj_; \
657 \
658 vec_assert (vec_->num, "pop"); \
659 obj_ = vec_->vec[--vec_->num]; \
660 \
661 return obj_; \
662 } \
663 \
664 static inline void VEC_OP (T,truncate) \
665 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
666 { \
667 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
668 if (vec_) \
669 vec_->num = size_; \
670 } \
671 \
672 static inline T VEC_OP (T,replace) \
673 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
674 { \
675 T old_obj_; \
676 \
677 vec_assert (ix_ < vec_->num, "replace"); \
678 old_obj_ = vec_->vec[ix_]; \
679 vec_->vec[ix_] = obj_; \
680 \
681 return old_obj_; \
682 } \
683 \
684 static inline T *VEC_OP (T,quick_insert) \
685 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
686 { \
687 T *slot_; \
688 \
689 vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
690 slot_ = &vec_->vec[ix_]; \
691 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
692 *slot_ = obj_; \
693 \
694 return slot_; \
695 } \
696 \
697 static inline T VEC_OP (T,ordered_remove) \
698 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
699 { \
700 T *slot_; \
701 T obj_; \
702 \
703 vec_assert (ix_ < vec_->num, "ordered_remove"); \
704 slot_ = &vec_->vec[ix_]; \
705 obj_ = *slot_; \
706 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
707 \
708 return obj_; \
709 } \
710 \
711 static inline T VEC_OP (T,unordered_remove) \
712 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
713 { \
714 T *slot_; \
715 T obj_; \
716 \
717 vec_assert (ix_ < vec_->num, "unordered_remove"); \
718 slot_ = &vec_->vec[ix_]; \
719 obj_ = *slot_; \
720 *slot_ = vec_->vec[--vec_->num]; \
721 \
722 return obj_; \
723 } \
724 \
725 static inline void VEC_OP (T,block_remove) \
726 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
727 { \
728 T *slot_; \
729 \
730 vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
731 slot_ = &vec_->vec[ix_]; \
732 vec_->num -= len_; \
733 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
734 } \
735 \
736 static inline T *VEC_OP (T,address) \
737 (VEC(T) *vec_) \
738 { \
739 return vec_ ? vec_->vec : 0; \
740 } \
741 \
742 static inline unsigned VEC_OP (T,lower_bound) \
743 (VEC(T) *vec_, const T obj_, \
744 int (*lessthan_)(const T, const T) VEC_ASSERT_DECL) \
745 { \
746 unsigned int len_ = VEC_OP (T, length) (vec_); \
747 unsigned int half_, middle_; \
748 unsigned int first_ = 0; \
749 while (len_ > 0) \
750 { \
751 T middle_elem_; \
752 half_ = len_ >> 1; \
753 middle_ = first_; \
754 middle_ += half_; \
755 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
756 if (lessthan_ (middle_elem_, obj_)) \
757 { \
758 first_ = middle_; \
759 ++first_; \
760 len_ = len_ - half_ - 1; \
761 } \
762 else \
763 len_ = half_; \
764 } \
765 return first_; \
766 }
767
768 #define DEF_VEC_ALLOC_FUNC_P(T) \
769 static inline VEC(T) *VEC_OP (T,alloc) \
770 (int alloc_) \
771 { \
772 /* We must request exact size allocation, hence the negation. */ \
773 return (VEC(T) *) vec_p_reserve (NULL, -alloc_); \
774 } \
775 \
776 static inline void VEC_OP (T,free) \
777 (VEC(T) **vec_) \
778 { \
779 if (*vec_) \
780 vec_free_ (*vec_); \
781 *vec_ = NULL; \
782 } \
783 \
784 static inline void VEC_OP (T,cleanup) \
785 (void *arg_) \
786 { \
787 VEC(T) **vec_ = (VEC(T) **) arg_; \
788 if (*vec_) \
789 vec_free_ (*vec_); \
790 *vec_ = NULL; \
791 } \
792 \
793 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
794 { \
795 size_t len_ = vec_ ? vec_->num : 0; \
796 VEC (T) *new_vec_ = NULL; \
797 \
798 if (len_) \
799 { \
800 /* We must request exact size allocation, hence the negation. */ \
801 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
802 \
803 new_vec_->num = len_; \
804 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
805 } \
806 return new_vec_; \
807 } \
808 \
809 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
810 { \
811 if (vec1_ && vec2_) \
812 { \
813 size_t len_ = vec1_->num + vec2_->num; \
814 VEC (T) *new_vec_ = NULL; \
815 \
816 /* We must request exact size allocation, hence the negation. */ \
817 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
818 \
819 new_vec_->num = len_; \
820 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
821 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
822 sizeof (T) * vec2_->num); \
823 \
824 return new_vec_; \
825 } \
826 else \
827 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
828 } \
829 \
830 static inline int VEC_OP (T,reserve) \
831 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
832 { \
833 int extend = !VEC_OP (T,space) \
834 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
835 \
836 if (extend) \
837 *vec_ = (VEC(T) *) vec_p_reserve (*vec_, alloc_); \
838 \
839 return extend; \
840 } \
841 \
842 static inline void VEC_OP (T,safe_grow) \
843 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
844 { \
845 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
846 "safe_grow"); \
847 VEC_OP (T,reserve) \
848 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
849 (*vec_)->num = size_; \
850 } \
851 \
852 static inline T *VEC_OP (T,safe_push) \
853 (VEC(T) **vec_, T obj_ VEC_ASSERT_DECL) \
854 { \
855 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
856 \
857 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
858 } \
859 \
860 static inline T *VEC_OP (T,safe_insert) \
861 (VEC(T) **vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
862 { \
863 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
864 \
865 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
866 }
867
868 #define DEF_VEC_FUNC_O(T) \
869 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
870 { \
871 return vec_ ? vec_->num : 0; \
872 } \
873 \
874 static inline T *VEC_OP (T,last) (VEC(T) *vec_ VEC_ASSERT_DECL) \
875 { \
876 vec_assert (vec_ && vec_->num, "last"); \
877 \
878 return &vec_->vec[vec_->num - 1]; \
879 } \
880 \
881 static inline T *VEC_OP (T,index) \
882 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
883 { \
884 vec_assert (vec_ && ix_ < vec_->num, "index"); \
885 \
886 return &vec_->vec[ix_]; \
887 } \
888 \
889 static inline int VEC_OP (T,iterate) \
890 (VEC(T) *vec_, unsigned ix_, T **ptr) \
891 { \
892 if (vec_ && ix_ < vec_->num) \
893 { \
894 *ptr = &vec_->vec[ix_]; \
895 return 1; \
896 } \
897 else \
898 { \
899 *ptr = 0; \
900 return 0; \
901 } \
902 } \
903 \
904 static inline size_t VEC_OP (T,embedded_size) \
905 (int alloc_) \
906 { \
907 VEC(T) dummy; \
908 \
909 return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
910 } \
911 \
912 static inline void VEC_OP (T,embedded_init) \
913 (VEC(T) *vec_, int alloc_) \
914 { \
915 vec_->num = 0; \
916 vec_->alloc = alloc_; \
917 } \
918 \
919 static inline int VEC_OP (T,space) \
920 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
921 { \
922 vec_assert (alloc_ >= 0, "space"); \
923 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
924 } \
925 \
926 static inline T *VEC_OP (T,quick_push) \
927 (VEC(T) *vec_, const T *obj_ VEC_ASSERT_DECL) \
928 { \
929 T *slot_; \
930 \
931 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
932 slot_ = &vec_->vec[vec_->num++]; \
933 if (obj_) \
934 *slot_ = *obj_; \
935 \
936 return slot_; \
937 } \
938 \
939 static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
940 { \
941 vec_assert (vec_->num, "pop"); \
942 --vec_->num; \
943 } \
944 \
945 static inline void VEC_OP (T,truncate) \
946 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
947 { \
948 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
949 if (vec_) \
950 vec_->num = size_; \
951 } \
952 \
953 static inline T *VEC_OP (T,replace) \
954 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
955 { \
956 T *slot_; \
957 \
958 vec_assert (ix_ < vec_->num, "replace"); \
959 slot_ = &vec_->vec[ix_]; \
960 if (obj_) \
961 *slot_ = *obj_; \
962 \
963 return slot_; \
964 } \
965 \
966 static inline T *VEC_OP (T,quick_insert) \
967 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
968 { \
969 T *slot_; \
970 \
971 vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
972 slot_ = &vec_->vec[ix_]; \
973 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
974 if (obj_) \
975 *slot_ = *obj_; \
976 \
977 return slot_; \
978 } \
979 \
980 static inline void VEC_OP (T,ordered_remove) \
981 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
982 { \
983 T *slot_; \
984 \
985 vec_assert (ix_ < vec_->num, "ordered_remove"); \
986 slot_ = &vec_->vec[ix_]; \
987 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
988 } \
989 \
990 static inline void VEC_OP (T,unordered_remove) \
991 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
992 { \
993 vec_assert (ix_ < vec_->num, "unordered_remove"); \
994 vec_->vec[ix_] = vec_->vec[--vec_->num]; \
995 } \
996 \
997 static inline void VEC_OP (T,block_remove) \
998 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
999 { \
1000 T *slot_; \
1001 \
1002 vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
1003 slot_ = &vec_->vec[ix_]; \
1004 vec_->num -= len_; \
1005 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
1006 } \
1007 \
1008 static inline T *VEC_OP (T,address) \
1009 (VEC(T) *vec_) \
1010 { \
1011 return vec_ ? vec_->vec : 0; \
1012 } \
1013 \
1014 static inline unsigned VEC_OP (T,lower_bound) \
1015 (VEC(T) *vec_, const T *obj_, \
1016 int (*lessthan_)(const T *, const T *) VEC_ASSERT_DECL) \
1017 { \
1018 unsigned int len_ = VEC_OP (T, length) (vec_); \
1019 unsigned int half_, middle_; \
1020 unsigned int first_ = 0; \
1021 while (len_ > 0) \
1022 { \
1023 T *middle_elem_; \
1024 half_ = len_ >> 1; \
1025 middle_ = first_; \
1026 middle_ += half_; \
1027 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
1028 if (lessthan_ (middle_elem_, obj_)) \
1029 { \
1030 first_ = middle_; \
1031 ++first_; \
1032 len_ = len_ - half_ - 1; \
1033 } \
1034 else \
1035 len_ = half_; \
1036 } \
1037 return first_; \
1038 }
1039
1040 #define DEF_VEC_ALLOC_FUNC_O(T) \
1041 static inline VEC(T) *VEC_OP (T,alloc) \
1042 (int alloc_) \
1043 { \
1044 VEC(T) dummy; \
1045 \
1046 /* We must request exact size allocation, hence the negation. */ \
1047 return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
1048 vec_offset (T, &dummy), sizeof (T)); \
1049 } \
1050 \
1051 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
1052 { \
1053 size_t len_ = vec_ ? vec_->num : 0; \
1054 VEC (T) *new_vec_ = NULL; \
1055 \
1056 if (len_) \
1057 { \
1058 VEC(T) dummy; \
1059 \
1060 /* We must request exact size allocation, hence the negation. */ \
1061 new_vec_ = (VEC (T) *) \
1062 vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
1063 \
1064 new_vec_->num = len_; \
1065 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
1066 } \
1067 return new_vec_; \
1068 } \
1069 \
1070 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
1071 { \
1072 if (vec1_ && vec2_) \
1073 { \
1074 VEC(T) dummy; \
1075 size_t len_ = vec1_->num + vec2_->num; \
1076 VEC (T) *new_vec_ = NULL; \
1077 \
1078 /* We must request exact size allocation, hence the negation. */ \
1079 new_vec_ = (VEC (T) *) \
1080 vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
1081 \
1082 new_vec_->num = len_; \
1083 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
1084 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
1085 sizeof (T) * vec2_->num); \
1086 \
1087 return new_vec_; \
1088 } \
1089 else \
1090 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
1091 } \
1092 \
1093 static inline void VEC_OP (T,free) \
1094 (VEC(T) **vec_) \
1095 { \
1096 if (*vec_) \
1097 vec_free_ (*vec_); \
1098 *vec_ = NULL; \
1099 } \
1100 \
1101 static inline void VEC_OP (T,cleanup) \
1102 (void *arg_) \
1103 { \
1104 VEC(T) **vec_ = (VEC(T) **) arg_; \
1105 if (*vec_) \
1106 vec_free_ (*vec_); \
1107 *vec_ = NULL; \
1108 } \
1109 \
1110 static inline int VEC_OP (T,reserve) \
1111 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
1112 { \
1113 VEC(T) dummy; \
1114 int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_ \
1115 VEC_ASSERT_PASS); \
1116 \
1117 if (extend) \
1118 *vec_ = (VEC(T) *) \
1119 vec_o_reserve (*vec_, alloc_, vec_offset (T, &dummy), sizeof (T)); \
1120 \
1121 return extend; \
1122 } \
1123 \
1124 static inline void VEC_OP (T,safe_grow) \
1125 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
1126 { \
1127 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
1128 "safe_grow"); \
1129 VEC_OP (T,reserve) \
1130 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
1131 (*vec_)->num = size_; \
1132 } \
1133 \
1134 static inline T *VEC_OP (T,safe_push) \
1135 (VEC(T) **vec_, const T *obj_ VEC_ASSERT_DECL) \
1136 { \
1137 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1138 \
1139 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
1140 } \
1141 \
1142 static inline T *VEC_OP (T,safe_insert) \
1143 (VEC(T) **vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
1144 { \
1145 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1146 \
1147 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
1148 }
1149
1150 #endif /* GDB_VEC_H */
vec_o_reserve
void * vec_o_reserve(void *, int, size_t, size_t)
Definition: vec.c:91
diagnostics.h
vec_p_reserve
void * vec_p_reserve(void *, int)
Definition: vec.c:80