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