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.  */
377extern void *vec_p_reserve (void *, int);
378extern 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)							  \
391typedef 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)							  \
400static inline void VEC_OP (T,must_be_integral_type) (void)		  \
401{									  \
402  (void)~(T)0;								  \
403}									  \
404									  \
405VEC_T(T);								  \
406DEF_VEC_FUNC_P(T)							  \
407DEF_VEC_ALLOC_FUNC_I(T)							  \
408struct vec_swallow_trailing_semi
409
410/* Vector of pointer to object.  */
411#define DEF_VEC_P(T)							  \
412static inline void VEC_OP (T,must_be_pointer_type) (void)		  \
413{									  \
414  (void)((T)1 == (void *)1);						  \
415}									  \
416									  \
417VEC_T(T);								  \
418DEF_VEC_FUNC_P(T)							  \
419DEF_VEC_ALLOC_FUNC_P(T)							  \
420struct vec_swallow_trailing_semi
421
422/* Vector of object.  */
423#define DEF_VEC_O(T)							  \
424VEC_T(T);								  \
425DEF_VEC_FUNC_O(T)							  \
426DEF_VEC_ALLOC_FUNC_O(T)							  \
427struct vec_swallow_trailing_semi
428
429#define DEF_VEC_ALLOC_FUNC_I(T)						  \
430static 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									  \
438static 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									  \
455static inline void VEC_OP (T,free)					  \
456     (VEC(T) **vec_)							  \
457{									  \
458  if (*vec_)								  \
459    vec_free_ (*vec_);							  \
460  *vec_ = NULL;								  \
461}									  \
462									  \
463static 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									  \
476static 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									  \
486static 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									  \
494static 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)						  \
503static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_)		  \
504{									  \
505  return vec_ ? vec_->num : 0;						  \
506}									  \
507									  \
508static 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									  \
516static 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									  \
524static 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									  \
539static inline size_t VEC_OP (T,embedded_size)				  \
540     (int alloc_)							  \
541{									  \
542  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);			  \
543}									  \
544									  \
545static inline void VEC_OP (T,embedded_init)				  \
546     (VEC(T) *vec_, int alloc_)						  \
547{									  \
548  vec_->num = 0;							  \
549  vec_->alloc = alloc_;							  \
550}									  \
551									  \
552static 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									  \
559static 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									  \
571static 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									  \
581static 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									  \
589static 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									  \
601static 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									  \
614static 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									  \
628static 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									  \
642static 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									  \
653static inline T *VEC_OP (T,address)					  \
654     (VEC(T) *vec_)							  \
655{									  \
656  return vec_ ? vec_->vec : 0;						  \
657}									  \
658									  \
659static 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)						  \
686static 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									  \
693static inline void VEC_OP (T,free)					  \
694     (VEC(T) **vec_)							  \
695{									  \
696  if (*vec_)								  \
697    vec_free_ (*vec_);							  \
698  *vec_ = NULL;								  \
699}									  \
700									  \
701static 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									  \
717static 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									  \
729static 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									  \
739static 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									  \
747static 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)						  \
756static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_)		  \
757{									  \
758  return vec_ ? vec_->num : 0;						  \
759}									  \
760									  \
761static 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									  \
768static 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									  \
776static 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									  \
791static inline size_t VEC_OP (T,embedded_size)				  \
792     (int alloc_)							  \
793{									  \
794  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);			  \
795}									  \
796									  \
797static inline void VEC_OP (T,embedded_init)				  \
798     (VEC(T) *vec_, int alloc_)						  \
799{									  \
800  vec_->num = 0;							  \
801  vec_->alloc = alloc_;							  \
802}									  \
803									  \
804static 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									  \
811static 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									  \
824static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL)	  \
825{									  \
826  vec_assert (vec_->num, "pop");					  \
827  --vec_->num;								  \
828}									  \
829									  \
830static 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									  \
838static 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									  \
851static 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									  \
865static 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									  \
875static 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									  \
882static 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									  \
893static inline T *VEC_OP (T,address)					  \
894     (VEC(T) *vec_)							  \
895{									  \
896  return vec_ ? vec_->vec : 0;						  \
897}									  \
898									  \
899static 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)						  \
926static 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									  \
934static 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									  \
951static inline void VEC_OP (T,free)					  \
952     (VEC(T) **vec_)							  \
953{									  \
954  if (*vec_)								  \
955    vec_free_ (*vec_);							  \
956  *vec_ = NULL;								  \
957}									  \
958									  \
959static 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									  \
972static 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									  \
982static 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									  \
990static 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 */
999