2 Copyright (C) 2004-2019 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
5 This file is part of GDB.
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.
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.
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/>. */
23 #include "diagnostics.h"
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:
28 https://bugs.llvm.org/show_bug.cgi?id=22712
30 We specifically ignore this warning for the vec functions when the compiler
33 # define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
34 DIAGNOSTIC_IGNORE_UNUSED_FUNCTION
36 # define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION
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.
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.
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.
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.
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.
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.
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.
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.
111 An example of their use would be,
113 DEF_VEC_P(tree); // non-managed tree vector.
116 VEC(tree) *v; // A (pointer to) a vector of tree pointers.
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 }
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. */
135 unsigned VEC_T_length(const VEC(T) *v);
137 Return the number of active elements in V. V can be NULL, in which
138 case zero is returned. */
140 #define VEC_length(T,V) (VEC_OP(T,length)(V))
143 /* Check if vector is empty
144 int VEC_T_empty(const VEC(T) *v);
146 Return nonzero if V is an empty vector (or V is NULL), zero otherwise. */
148 #define VEC_empty(T,V) (VEC_length (T,V) == 0)
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
156 Return the final element. V must not be empty. */
158 #define VEC_last(T,V) (VEC_OP(T,last)(V VEC_ASSERT_INFO))
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
165 Return the IX'th element. If IX must be in the domain of V. */
167 #define VEC_index(T,V,I) (VEC_OP(T,index)(V,I VEC_ASSERT_INFO))
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
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,
178 for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
181 #define VEC_iterate(T,V,I,P) (VEC_OP(T,iterate)(V,I,&(P)))
183 /* Allocate new vector.
184 VEC(T,A) *VEC_T_alloc(int reserve);
186 Allocate a new vector with space for RESERVE objects. If RESERVE
187 is zero, NO vector is created. */
189 #define VEC_alloc(T,N) (VEC_OP(T,alloc)(N))
192 void VEC_T_free(VEC(T,A) *&);
194 Free a vector and set it to NULL. */
196 #define VEC_free(T,V) (VEC_OP(T,free)(&V))
198 /* A cleanup function for a vector.
199 void VEC_T_cleanup(void *);
201 Clean up a vector. */
203 #define VEC_cleanup(T) (VEC_OP(T,cleanup))
205 /* Use these to determine the required size and initialization of a
206 vector embedded within another structure (as the final member).
208 size_t VEC_T_embedded_size(int reserve);
209 void VEC_T_embedded_init(VEC(T) *v, int reserve);
211 These allow the caller to perform the memory allocation. */
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))
217 VEC(T,A) *VEC_T_copy(VEC(T) *);
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. */
222 #define VEC_copy(T,V) (VEC_OP(T,copy)(V))
224 /* Merge two vectors.
225 VEC(T,A) *VEC_T_merge(VEC(T) *, VEC(T) *);
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))
231 /* Determine if a vector has additional capacity.
233 int VEC_T_space (VEC(T) *v,int reserve)
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
241 #define VEC_space(T,V,R) (VEC_OP(T,space)(V,R VEC_ASSERT_INFO))
244 int VEC_T_reserve(VEC(T,A) *&v, int reserve);
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. */
253 #define VEC_reserve(T,V,R) (VEC_OP(T,reserve)(&(V),R VEC_ASSERT_INFO))
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
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. */
265 #define VEC_quick_push(T,V,O) (VEC_OP(T,quick_push)(V,O VEC_ASSERT_INFO))
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
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. */
276 #define VEC_safe_push(T,V,O) (VEC_OP(T,safe_push)(&(V),O VEC_ASSERT_INFO))
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
283 Pop the last element off the end. Returns the element popped, for
286 #define VEC_pop(T,V) (VEC_OP(T,pop)(V VEC_ASSERT_INFO))
288 /* Truncate to specific length
289 void VEC_T_truncate (VEC(T) *v, unsigned len);
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. */
294 #define VEC_truncate(T,V,I) \
295 (VEC_OP(T,truncate)(V,I VEC_ASSERT_INFO))
297 /* Grow to a specific length.
298 void VEC_T_safe_grow (VEC(T,A) *&v, int len);
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
304 #define VEC_safe_grow(T,V,I) \
305 (VEC_OP(T,safe_grow)(&(V),I VEC_ASSERT_INFO))
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
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
318 #define VEC_replace(T,V,I,O) (VEC_OP(T,replace)(V,I,O VEC_ASSERT_INFO))
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
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. */
330 #define VEC_quick_insert(T,V,I,O) \
331 (VEC_OP(T,quick_insert)(V,I,O VEC_ASSERT_INFO))
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
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. */
343 #define VEC_safe_insert(T,V,I,O) \
344 (VEC_OP(T,safe_insert)(&(V),I,O VEC_ASSERT_INFO))
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
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. */
355 #define VEC_ordered_remove(T,V,I) \
356 (VEC_OP(T,ordered_remove)(V,I VEC_ASSERT_INFO))
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
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. */
367 #define VEC_unordered_remove(T,V,I) \
368 (VEC_OP(T,unordered_remove)(V,I VEC_ASSERT_INFO))
370 /* Remove a block of elements
371 void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
373 Remove LEN elements starting at the IXth. Ordering is retained.
374 This is an O(N) operation due to memmove. */
376 #define VEC_block_remove(T,V,I,L) \
377 (VEC_OP(T,block_remove)(V,I,L VEC_ASSERT_INFO))
379 /* Get the address of the array of elements
380 T *VEC_T_address (VEC(T) v)
382 If you need to directly manipulate the array (for instance, you
383 want to feed it to qsort), use this accessor. */
385 #define VEC_address(T,V) (VEC_OP(T,address)(V))
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
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. */
399 #define VEC_lower_bound(T,V,O,LT) \
400 (VEC_OP(T,lower_bound)(V,O,LT VEC_ASSERT_INFO))
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)
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_, \
414 #define VEC(T) VEC_##T
415 #define VEC_OP(T,OP) VEC_##T##_##OP
418 typedef struct VEC(T) \
425 /* Vector of integer-like object. */
426 #define DEF_VEC_I(T) \
428 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
429 static inline void VEC_OP (T,must_be_integral_type) (void) \
436 DEF_VEC_ALLOC_FUNC_I(T) \
438 struct vec_swallow_trailing_semi
440 /* Vector of pointer to object. */
441 #define DEF_VEC_P(T) \
443 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
444 static inline void VEC_OP (T,must_be_pointer_type) (void) \
446 (void)((T)1 == (void *)1); \
451 DEF_VEC_ALLOC_FUNC_P(T) \
453 struct vec_swallow_trailing_semi
455 /* Vector of object. */
456 #define DEF_VEC_O(T) \
458 DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
461 DEF_VEC_ALLOC_FUNC_O(T) \
463 struct vec_swallow_trailing_semi
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))
473 #define DEF_VEC_ALLOC_FUNC_I(T) \
474 static inline VEC(T) *VEC_OP (T,alloc) \
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)); \
484 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
486 size_t len_ = vec_ ? vec_->num : 0; \
487 VEC (T) *new_vec_ = NULL; \
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)); \
497 new_vec_->num = len_; \
498 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
503 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
505 if (vec1_ && vec2_) \
508 size_t len_ = vec1_->num + vec2_->num; \
509 VEC (T) *new_vec_ = NULL; \
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)); \
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); \
523 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
526 static inline void VEC_OP (T,free) \
534 static inline void VEC_OP (T,cleanup) \
537 VEC(T) **vec_ = (VEC(T) **) arg_; \
543 static inline int VEC_OP (T,reserve) \
544 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
547 int extend = !VEC_OP (T,space) \
548 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
551 *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_, \
552 vec_offset (T, &dummy), sizeof (T)); \
557 static inline void VEC_OP (T,safe_grow) \
558 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
560 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
562 VEC_OP (T,reserve) (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ \
564 (*vec_)->num = size_; \
567 static inline T *VEC_OP (T,safe_push) \
568 (VEC(T) **vec_, const T obj_ VEC_ASSERT_DECL) \
570 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
572 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
575 static inline T *VEC_OP (T,safe_insert) \
576 (VEC(T) **vec_, unsigned ix_, const T obj_ VEC_ASSERT_DECL) \
578 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
580 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
583 #define DEF_VEC_FUNC_P(T) \
584 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
586 return vec_ ? vec_->num : 0; \
589 static inline T VEC_OP (T,last) \
590 (const VEC(T) *vec_ VEC_ASSERT_DECL) \
592 vec_assert (vec_ && vec_->num, "last"); \
594 return vec_->vec[vec_->num - 1]; \
597 static inline T VEC_OP (T,index) \
598 (const VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
600 vec_assert (vec_ && ix_ < vec_->num, "index"); \
602 return vec_->vec[ix_]; \
605 static inline int VEC_OP (T,iterate) \
606 (const VEC(T) *vec_, unsigned ix_, T *ptr) \
608 if (vec_ && ix_ < vec_->num) \
610 *ptr = vec_->vec[ix_]; \
620 static inline size_t VEC_OP (T,embedded_size) \
625 return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
628 static inline void VEC_OP (T,embedded_init) \
629 (VEC(T) *vec_, int alloc_) \
632 vec_->alloc = alloc_; \
635 static inline int VEC_OP (T,space) \
636 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
638 vec_assert (alloc_ >= 0, "space"); \
639 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
642 static inline T *VEC_OP (T,quick_push) \
643 (VEC(T) *vec_, T obj_ VEC_ASSERT_DECL) \
647 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
648 slot_ = &vec_->vec[vec_->num++]; \
654 static inline T VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
658 vec_assert (vec_->num, "pop"); \
659 obj_ = vec_->vec[--vec_->num]; \
664 static inline void VEC_OP (T,truncate) \
665 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
667 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
672 static inline T VEC_OP (T,replace) \
673 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
677 vec_assert (ix_ < vec_->num, "replace"); \
678 old_obj_ = vec_->vec[ix_]; \
679 vec_->vec[ix_] = obj_; \
684 static inline T *VEC_OP (T,quick_insert) \
685 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
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)); \
697 static inline T VEC_OP (T,ordered_remove) \
698 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
703 vec_assert (ix_ < vec_->num, "ordered_remove"); \
704 slot_ = &vec_->vec[ix_]; \
706 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
711 static inline T VEC_OP (T,unordered_remove) \
712 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
717 vec_assert (ix_ < vec_->num, "unordered_remove"); \
718 slot_ = &vec_->vec[ix_]; \
720 *slot_ = vec_->vec[--vec_->num]; \
725 static inline void VEC_OP (T,block_remove) \
726 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
730 vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
731 slot_ = &vec_->vec[ix_]; \
733 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
736 static inline T *VEC_OP (T,address) \
739 return vec_ ? vec_->vec : 0; \
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) \
746 unsigned int len_ = VEC_OP (T, length) (vec_); \
747 unsigned int half_, middle_; \
748 unsigned int first_ = 0; \
755 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
756 if (lessthan_ (middle_elem_, obj_)) \
760 len_ = len_ - half_ - 1; \
768 #define DEF_VEC_ALLOC_FUNC_P(T) \
769 static inline VEC(T) *VEC_OP (T,alloc) \
772 /* We must request exact size allocation, hence the negation. */ \
773 return (VEC(T) *) vec_p_reserve (NULL, -alloc_); \
776 static inline void VEC_OP (T,free) \
784 static inline void VEC_OP (T,cleanup) \
787 VEC(T) **vec_ = (VEC(T) **) arg_; \
793 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
795 size_t len_ = vec_ ? vec_->num : 0; \
796 VEC (T) *new_vec_ = NULL; \
800 /* We must request exact size allocation, hence the negation. */ \
801 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
803 new_vec_->num = len_; \
804 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
809 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
811 if (vec1_ && vec2_) \
813 size_t len_ = vec1_->num + vec2_->num; \
814 VEC (T) *new_vec_ = NULL; \
816 /* We must request exact size allocation, hence the negation. */ \
817 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
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); \
827 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
830 static inline int VEC_OP (T,reserve) \
831 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
833 int extend = !VEC_OP (T,space) \
834 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
837 *vec_ = (VEC(T) *) vec_p_reserve (*vec_, alloc_); \
842 static inline void VEC_OP (T,safe_grow) \
843 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
845 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
848 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
849 (*vec_)->num = size_; \
852 static inline T *VEC_OP (T,safe_push) \
853 (VEC(T) **vec_, T obj_ VEC_ASSERT_DECL) \
855 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
857 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
860 static inline T *VEC_OP (T,safe_insert) \
861 (VEC(T) **vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
863 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
865 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
868 #define DEF_VEC_FUNC_O(T) \
869 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
871 return vec_ ? vec_->num : 0; \
874 static inline T *VEC_OP (T,last) (VEC(T) *vec_ VEC_ASSERT_DECL) \
876 vec_assert (vec_ && vec_->num, "last"); \
878 return &vec_->vec[vec_->num - 1]; \
881 static inline T *VEC_OP (T,index) \
882 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
884 vec_assert (vec_ && ix_ < vec_->num, "index"); \
886 return &vec_->vec[ix_]; \
889 static inline int VEC_OP (T,iterate) \
890 (VEC(T) *vec_, unsigned ix_, T **ptr) \
892 if (vec_ && ix_ < vec_->num) \
894 *ptr = &vec_->vec[ix_]; \
904 static inline size_t VEC_OP (T,embedded_size) \
909 return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
912 static inline void VEC_OP (T,embedded_init) \
913 (VEC(T) *vec_, int alloc_) \
916 vec_->alloc = alloc_; \
919 static inline int VEC_OP (T,space) \
920 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
922 vec_assert (alloc_ >= 0, "space"); \
923 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
926 static inline T *VEC_OP (T,quick_push) \
927 (VEC(T) *vec_, const T *obj_ VEC_ASSERT_DECL) \
931 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
932 slot_ = &vec_->vec[vec_->num++]; \
939 static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
941 vec_assert (vec_->num, "pop"); \
945 static inline void VEC_OP (T,truncate) \
946 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
948 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
953 static inline T *VEC_OP (T,replace) \
954 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
958 vec_assert (ix_ < vec_->num, "replace"); \
959 slot_ = &vec_->vec[ix_]; \
966 static inline T *VEC_OP (T,quick_insert) \
967 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
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)); \
980 static inline void VEC_OP (T,ordered_remove) \
981 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
985 vec_assert (ix_ < vec_->num, "ordered_remove"); \
986 slot_ = &vec_->vec[ix_]; \
987 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
990 static inline void VEC_OP (T,unordered_remove) \
991 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
993 vec_assert (ix_ < vec_->num, "unordered_remove"); \
994 vec_->vec[ix_] = vec_->vec[--vec_->num]; \
997 static inline void VEC_OP (T,block_remove) \
998 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
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)); \
1008 static inline T *VEC_OP (T,address) \
1011 return vec_ ? vec_->vec : 0; \
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) \
1018 unsigned int len_ = VEC_OP (T, length) (vec_); \
1019 unsigned int half_, middle_; \
1020 unsigned int first_ = 0; \
1024 half_ = len_ >> 1; \
1027 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
1028 if (lessthan_ (middle_elem_, obj_)) \
1032 len_ = len_ - half_ - 1; \
1040 #define DEF_VEC_ALLOC_FUNC_O(T) \
1041 static inline VEC(T) *VEC_OP (T,alloc) \
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)); \
1051 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
1053 size_t len_ = vec_ ? vec_->num : 0; \
1054 VEC (T) *new_vec_ = NULL; \
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)); \
1064 new_vec_->num = len_; \
1065 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
1070 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
1072 if (vec1_ && vec2_) \
1075 size_t len_ = vec1_->num + vec2_->num; \
1076 VEC (T) *new_vec_ = NULL; \
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)); \
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); \
1090 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
1093 static inline void VEC_OP (T,free) \
1097 vec_free_ (*vec_); \
1101 static inline void VEC_OP (T,cleanup) \
1104 VEC(T) **vec_ = (VEC(T) **) arg_; \
1106 vec_free_ (*vec_); \
1110 static inline int VEC_OP (T,reserve) \
1111 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
1114 int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_ \
1118 *vec_ = (VEC(T) *) \
1119 vec_o_reserve (*vec_, alloc_, vec_offset (T, &dummy), sizeof (T)); \
1124 static inline void VEC_OP (T,safe_grow) \
1125 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
1127 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
1129 VEC_OP (T,reserve) \
1130 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
1131 (*vec_)->num = size_; \
1134 static inline T *VEC_OP (T,safe_push) \
1135 (VEC(T) **vec_, const T *obj_ VEC_ASSERT_DECL) \
1137 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1139 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
1142 static inline T *VEC_OP (T,safe_insert) \
1143 (VEC(T) **vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
1145 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1147 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
1150 #endif /* COMMON_VEC_H */