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