xref: /dflybsd-src/contrib/gcc-4.7/gcc/vec.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Vector API for GNU compiler.
2*e4b17023SJohn Marino    Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Nathan Sidwell <nathan@codesourcery.com>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #ifndef GCC_VEC_H
23*e4b17023SJohn Marino #define GCC_VEC_H
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino #include "statistics.h"		/* For MEM_STAT_DECL.  */
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino /* The macros here implement a set of templated vector types and
28*e4b17023SJohn Marino    associated interfaces.  These templates are implemented with
29*e4b17023SJohn Marino    macros, as we're not in C++ land.  The interface functions are
30*e4b17023SJohn Marino    typesafe and use static inline functions, sometimes backed by
31*e4b17023SJohn Marino    out-of-line generic functions.  The vectors are designed to
32*e4b17023SJohn Marino    interoperate with the GTY machinery.
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino    Because of the different behavior of structure objects, scalar
35*e4b17023SJohn Marino    objects and of pointers, there are three flavors, one for each of
36*e4b17023SJohn Marino    these variants.  Both the structure object and pointer variants
37*e4b17023SJohn Marino    pass pointers to objects around -- in the former case the pointers
38*e4b17023SJohn Marino    are stored into the vector and in the latter case the pointers are
39*e4b17023SJohn Marino    dereferenced and the objects copied into the vector.  The scalar
40*e4b17023SJohn Marino    object variant is suitable for int-like objects, and the vector
41*e4b17023SJohn Marino    elements are returned by value.
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino    There are both 'index' and 'iterate' accessors.  The iterator
44*e4b17023SJohn Marino    returns a boolean iteration condition and updates the iteration
45*e4b17023SJohn Marino    variable passed by reference.  Because the iterator will be
46*e4b17023SJohn Marino    inlined, the address-of can be optimized away.
47*e4b17023SJohn Marino 
48*e4b17023SJohn Marino    The vectors are implemented using the trailing array idiom, thus
49*e4b17023SJohn Marino    they are not resizeable without changing the address of the vector
50*e4b17023SJohn Marino    object itself.  This means you cannot have variables or fields of
51*e4b17023SJohn Marino    vector type -- always use a pointer to a vector.  The one exception
52*e4b17023SJohn Marino    is the final field of a structure, which could be a vector type.
53*e4b17023SJohn Marino    You will have to use the embedded_size & embedded_init calls to
54*e4b17023SJohn Marino    create such objects, and they will probably not be resizeable (so
55*e4b17023SJohn Marino    don't use the 'safe' allocation variants).  The trailing array
56*e4b17023SJohn Marino    idiom is used (rather than a pointer to an array of data), because,
57*e4b17023SJohn Marino    if we allow NULL to also represent an empty vector, empty vectors
58*e4b17023SJohn Marino    occupy minimal space in the structure containing them.
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino    Each operation that increases the number of active elements is
61*e4b17023SJohn Marino    available in 'quick' and 'safe' variants.  The former presumes that
62*e4b17023SJohn Marino    there is sufficient allocated space for the operation to succeed
63*e4b17023SJohn Marino    (it dies if there is not).  The latter will reallocate the
64*e4b17023SJohn Marino    vector, if needed.  Reallocation causes an exponential increase in
65*e4b17023SJohn Marino    vector size.  If you know you will be adding N elements, it would
66*e4b17023SJohn Marino    be more efficient to use the reserve operation before adding the
67*e4b17023SJohn Marino    elements with the 'quick' operation.  This will ensure there are at
68*e4b17023SJohn Marino    least as many elements as you ask for, it will exponentially
69*e4b17023SJohn Marino    increase if there are too few spare slots.  If you want reserve a
70*e4b17023SJohn Marino    specific number of slots, but do not want the exponential increase
71*e4b17023SJohn Marino    (for instance, you know this is the last allocation), use the
72*e4b17023SJohn Marino    reserve_exact operation.  You can also create a vector of a
73*e4b17023SJohn Marino    specific size from the get go.
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino    You should prefer the push and pop operations, as they append and
76*e4b17023SJohn Marino    remove from the end of the vector. If you need to remove several
77*e4b17023SJohn Marino    items in one go, use the truncate operation.  The insert and remove
78*e4b17023SJohn Marino    operations allow you to change elements in the middle of the
79*e4b17023SJohn Marino    vector.  There are two remove operations, one which preserves the
80*e4b17023SJohn Marino    element ordering 'ordered_remove', and one which does not
81*e4b17023SJohn Marino    'unordered_remove'.  The latter function copies the end element
82*e4b17023SJohn Marino    into the removed slot, rather than invoke a memmove operation.  The
83*e4b17023SJohn Marino    'lower_bound' function will determine where to place an item in the
84*e4b17023SJohn Marino    array using insert that will maintain sorted order.
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino    When a vector type is defined, first a non-memory managed version
87*e4b17023SJohn Marino    is created.  You can then define either or both garbage collected
88*e4b17023SJohn Marino    and heap allocated versions.  The allocation mechanism is specified
89*e4b17023SJohn Marino    when the type is defined, and is therefore part of the type.  If
90*e4b17023SJohn Marino    you need both gc'd and heap allocated versions, you still must have
91*e4b17023SJohn Marino    *exactly* one definition of the common non-memory managed base vector.
92*e4b17023SJohn Marino 
93*e4b17023SJohn Marino    If you need to directly manipulate a vector, then the 'address'
94*e4b17023SJohn Marino    accessor will return the address of the start of the vector.  Also
95*e4b17023SJohn Marino    the 'space' predicate will tell you whether there is spare capacity
96*e4b17023SJohn Marino    in the vector.  You will not normally need to use these two functions.
97*e4b17023SJohn Marino 
98*e4b17023SJohn Marino    Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
99*e4b17023SJohn Marino    get the non-memory allocation version, and then a
100*e4b17023SJohn Marino    DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
101*e4b17023SJohn Marino    vectors.  Variables of vector type are declared using a
102*e4b17023SJohn Marino    VEC(TYPEDEF,ALLOC) macro.  The ALLOC argument specifies the
103*e4b17023SJohn Marino    allocation strategy, and can be either 'gc' or 'heap' for garbage
104*e4b17023SJohn Marino    collected and heap allocated respectively.  It can be 'none' to get
105*e4b17023SJohn Marino    a vector that must be explicitly allocated (for instance as a
106*e4b17023SJohn Marino    trailing array of another structure).  The characters O, P and I
107*e4b17023SJohn Marino    indicate whether TYPEDEF is a pointer (P), object (O) or integral
108*e4b17023SJohn Marino    (I) type.  Be careful to pick the correct one, as you'll get an
109*e4b17023SJohn Marino    awkward and inefficient API if you use the wrong one.  There is a
110*e4b17023SJohn Marino    check, which results in a compile-time warning, for the P and I
111*e4b17023SJohn Marino    versions, but there is no check for the O versions, as that is not
112*e4b17023SJohn Marino    possible in plain C.  Due to the way GTY works, you must annotate
113*e4b17023SJohn Marino    any structures you wish to insert or reference from a vector with a
114*e4b17023SJohn Marino    GTY(()) tag.  You need to do this even if you never declare the GC
115*e4b17023SJohn Marino    allocated variants.
116*e4b17023SJohn Marino 
117*e4b17023SJohn Marino    An example of their use would be,
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino    DEF_VEC_P(tree);   // non-managed tree vector.
120*e4b17023SJohn Marino    DEF_VEC_ALLOC_P(tree,gc);	// gc'd vector of tree pointers.  This must
121*e4b17023SJohn Marino    			        // appear at file scope.
122*e4b17023SJohn Marino 
123*e4b17023SJohn Marino    struct my_struct {
124*e4b17023SJohn Marino      VEC(tree,gc) *v;      // A (pointer to) a vector of tree pointers.
125*e4b17023SJohn Marino    };
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino    struct my_struct *s;
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino    if (VEC_length(tree,s->v)) { we have some contents }
130*e4b17023SJohn Marino    VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
131*e4b17023SJohn Marino    for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
132*e4b17023SJohn Marino      { do something with elt }
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino */
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino /* Macros to invoke API calls.  A single macro works for both pointer
137*e4b17023SJohn Marino    and object vectors, but the argument and return types might well be
138*e4b17023SJohn Marino    different.  In each macro, T is the typedef of the vector elements,
139*e4b17023SJohn Marino    and A is the allocation strategy.  The allocation strategy is only
140*e4b17023SJohn Marino    present when it is required.  Some of these macros pass the vector,
141*e4b17023SJohn Marino    V, by reference (by taking its address), this is noted in the
142*e4b17023SJohn Marino    descriptions.  */
143*e4b17023SJohn Marino 
144*e4b17023SJohn Marino /* Length of vector
145*e4b17023SJohn Marino    unsigned VEC_T_length(const VEC(T) *v);
146*e4b17023SJohn Marino 
147*e4b17023SJohn Marino    Return the number of active elements in V.  V can be NULL, in which
148*e4b17023SJohn Marino    case zero is returned.  */
149*e4b17023SJohn Marino 
150*e4b17023SJohn Marino #define VEC_length(T,V)	(VEC_OP(T,base,length)(VEC_BASE(V)))
151*e4b17023SJohn Marino 
152*e4b17023SJohn Marino 
153*e4b17023SJohn Marino /* Check if vector is empty
154*e4b17023SJohn Marino    int VEC_T_empty(const VEC(T) *v);
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino    Return nonzero if V is an empty vector (or V is NULL), zero otherwise.  */
157*e4b17023SJohn Marino 
158*e4b17023SJohn Marino #define VEC_empty(T,V)	(VEC_length (T,V) == 0)
159*e4b17023SJohn Marino 
160*e4b17023SJohn Marino 
161*e4b17023SJohn Marino /* Get the final element of the vector.
162*e4b17023SJohn Marino    T VEC_T_last(VEC(T) *v); // Integer
163*e4b17023SJohn Marino    T VEC_T_last(VEC(T) *v); // Pointer
164*e4b17023SJohn Marino    T *VEC_T_last(VEC(T) *v); // Object
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino    Return the final element.  V must not be empty.  */
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino #define VEC_last(T,V)	(VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino /* Index into vector
171*e4b17023SJohn Marino    T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
172*e4b17023SJohn Marino    T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
173*e4b17023SJohn Marino    T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino    Return the IX'th element.  If IX must be in the domain of V.  */
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino #define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
178*e4b17023SJohn Marino 
179*e4b17023SJohn Marino /* Iterate over vector
180*e4b17023SJohn Marino    int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
181*e4b17023SJohn Marino    int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
182*e4b17023SJohn Marino    int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
183*e4b17023SJohn Marino 
184*e4b17023SJohn Marino    Return iteration condition and update PTR to point to the IX'th
185*e4b17023SJohn Marino    element.  At the end of iteration, sets PTR to NULL.  Use this to
186*e4b17023SJohn Marino    iterate over the elements of a vector as follows,
187*e4b17023SJohn Marino 
188*e4b17023SJohn Marino      for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
189*e4b17023SJohn Marino        continue;  */
190*e4b17023SJohn Marino 
191*e4b17023SJohn Marino #define VEC_iterate(T,V,I,P)	(VEC_OP(T,base,iterate)(VEC_BASE(V),I,&(P)))
192*e4b17023SJohn Marino 
193*e4b17023SJohn Marino /* Convenience macro for forward iteration.  */
194*e4b17023SJohn Marino 
195*e4b17023SJohn Marino #define FOR_EACH_VEC_ELT(T, V, I, P)		\
196*e4b17023SJohn Marino   for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))
197*e4b17023SJohn Marino 
198*e4b17023SJohn Marino /* Likewise, but start from FROM rather than 0.  */
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino #define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM)		\
201*e4b17023SJohn Marino   for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))
202*e4b17023SJohn Marino 
203*e4b17023SJohn Marino /* Convenience macro for reverse iteration.  */
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino #define FOR_EACH_VEC_ELT_REVERSE(T,V,I,P) \
206*e4b17023SJohn Marino   for (I = VEC_length (T, (V)) - 1;           \
207*e4b17023SJohn Marino        VEC_iterate (T, (V), (I), (P));	  \
208*e4b17023SJohn Marino        (I)--)
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino /* Allocate new vector.
211*e4b17023SJohn Marino    VEC(T,A) *VEC_T_A_alloc(int reserve);
212*e4b17023SJohn Marino 
213*e4b17023SJohn Marino    Allocate a new vector with space for RESERVE objects.  If RESERVE
214*e4b17023SJohn Marino    is zero, NO vector is created.  */
215*e4b17023SJohn Marino 
216*e4b17023SJohn Marino #define VEC_alloc(T,A,N)	(VEC_OP(T,A,alloc)(N MEM_STAT_INFO))
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino /* Free a vector.
219*e4b17023SJohn Marino    void VEC_T_A_free(VEC(T,A) *&);
220*e4b17023SJohn Marino 
221*e4b17023SJohn Marino    Free a vector and set it to NULL.  */
222*e4b17023SJohn Marino 
223*e4b17023SJohn Marino #define VEC_free(T,A,V)	(VEC_OP(T,A,free)(&V))
224*e4b17023SJohn Marino 
225*e4b17023SJohn Marino /* Use these to determine the required size and initialization of a
226*e4b17023SJohn Marino    vector embedded within another structure (as the final member).
227*e4b17023SJohn Marino 
228*e4b17023SJohn Marino    size_t VEC_T_embedded_size(int reserve);
229*e4b17023SJohn Marino    void VEC_T_embedded_init(VEC(T) *v, int reserve);
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino    These allow the caller to perform the memory allocation.  */
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino #define VEC_embedded_size(T,N)	 (VEC_OP(T,base,embedded_size)(N))
234*e4b17023SJohn Marino #define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N))
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino /* Copy a vector.
237*e4b17023SJohn Marino    VEC(T,A) *VEC_T_A_copy(VEC(T) *);
238*e4b17023SJohn Marino 
239*e4b17023SJohn Marino    Copy the live elements of a vector into a new vector.  The new and
240*e4b17023SJohn Marino    old vectors need not be allocated by the same mechanism.  */
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino #define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO))
243*e4b17023SJohn Marino 
244*e4b17023SJohn Marino /* Determine if a vector has additional capacity.
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino    int VEC_T_space (VEC(T) *v,int reserve)
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino    If V has space for RESERVE additional entries, return nonzero.  You
249*e4b17023SJohn Marino    usually only need to use this if you are doing your own vector
250*e4b17023SJohn Marino    reallocation, for instance on an embedded vector.  This returns
251*e4b17023SJohn Marino    nonzero in exactly the same circumstances that VEC_T_reserve
252*e4b17023SJohn Marino    will.  */
253*e4b17023SJohn Marino 
254*e4b17023SJohn Marino #define VEC_space(T,V,R) \
255*e4b17023SJohn Marino 	(VEC_OP(T,base,space)(VEC_BASE(V),R VEC_CHECK_INFO))
256*e4b17023SJohn Marino 
257*e4b17023SJohn Marino /* Reserve space.
258*e4b17023SJohn Marino    int VEC_T_A_reserve(VEC(T,A) *&v, int reserve);
259*e4b17023SJohn Marino 
260*e4b17023SJohn Marino    Ensure that V has at least RESERVE slots available.  This will
261*e4b17023SJohn Marino    create additional headroom.  Note this can cause V to be
262*e4b17023SJohn Marino    reallocated.  Returns nonzero iff reallocation actually
263*e4b17023SJohn Marino    occurred.  */
264*e4b17023SJohn Marino 
265*e4b17023SJohn Marino #define VEC_reserve(T,A,V,R)	\
266*e4b17023SJohn Marino 	(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
267*e4b17023SJohn Marino 
268*e4b17023SJohn Marino /* Reserve space exactly.
269*e4b17023SJohn Marino    int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve);
270*e4b17023SJohn Marino 
271*e4b17023SJohn Marino    Ensure that V has at least RESERVE slots available.  This will not
272*e4b17023SJohn Marino    create additional headroom.  Note this can cause V to be
273*e4b17023SJohn Marino    reallocated.  Returns nonzero iff reallocation actually
274*e4b17023SJohn Marino    occurred.  */
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino #define VEC_reserve_exact(T,A,V,R)	\
277*e4b17023SJohn Marino 	(VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
278*e4b17023SJohn Marino 
279*e4b17023SJohn Marino /* Copy elements with no reallocation
280*e4b17023SJohn Marino    void VEC_T_splice (VEC(T) *dst, VEC(T) *src); // Integer
281*e4b17023SJohn Marino    void VEC_T_splice (VEC(T) *dst, VEC(T) *src); // Pointer
282*e4b17023SJohn Marino    void VEC_T_splice (VEC(T) *dst, VEC(T) *src); // Object
283*e4b17023SJohn Marino 
284*e4b17023SJohn Marino    Copy the elements in SRC to the end of DST as if by memcpy.  DST and
285*e4b17023SJohn Marino    SRC need not be allocated with the same mechanism, although they most
286*e4b17023SJohn Marino    often will be.  DST is assumed to have sufficient headroom
287*e4b17023SJohn Marino    available.  */
288*e4b17023SJohn Marino 
289*e4b17023SJohn Marino #define VEC_splice(T,DST,SRC)			\
290*e4b17023SJohn Marino   (VEC_OP(T,base,splice)(VEC_BASE(DST), VEC_BASE(SRC) VEC_CHECK_INFO))
291*e4b17023SJohn Marino 
292*e4b17023SJohn Marino /* Copy elements with reallocation
293*e4b17023SJohn Marino    void VEC_T_safe_splice (VEC(T,A) *&dst, VEC(T) *src); // Integer
294*e4b17023SJohn Marino    void VEC_T_safe_splice (VEC(T,A) *&dst, VEC(T) *src); // Pointer
295*e4b17023SJohn Marino    void VEC_T_safe_splice (VEC(T,A) *&dst, VEC(T) *src); // Object
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino    Copy the elements in SRC to the end of DST as if by memcpy.  DST and
298*e4b17023SJohn Marino    SRC need not be allocated with the same mechanism, although they most
299*e4b17023SJohn Marino    often will be.  DST need not have sufficient headroom and will be
300*e4b17023SJohn Marino    reallocated if needed.  */
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino #define VEC_safe_splice(T,A,DST,SRC)					\
303*e4b17023SJohn Marino   (VEC_OP(T,A,safe_splice)(&(DST), VEC_BASE(SRC) VEC_CHECK_INFO MEM_STAT_INFO))
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino /* Push object with no reallocation
306*e4b17023SJohn Marino    T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
307*e4b17023SJohn Marino    T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
308*e4b17023SJohn Marino    T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
309*e4b17023SJohn Marino 
310*e4b17023SJohn Marino    Push a new element onto the end, returns a pointer to the slot
311*e4b17023SJohn Marino    filled in. For object vectors, the new value can be NULL, in which
312*e4b17023SJohn Marino    case NO initialization is performed.  There must
313*e4b17023SJohn Marino    be sufficient space in the vector.  */
314*e4b17023SJohn Marino 
315*e4b17023SJohn Marino #define VEC_quick_push(T,V,O)	\
316*e4b17023SJohn Marino 	(VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino /* Push object with reallocation
319*e4b17023SJohn Marino    T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
320*e4b17023SJohn Marino    T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
321*e4b17023SJohn Marino    T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino    Push a new element onto the end, returns a pointer to the slot
324*e4b17023SJohn Marino    filled in. For object vectors, the new value can be NULL, in which
325*e4b17023SJohn Marino    case NO initialization is performed.  Reallocates V, if needed.  */
326*e4b17023SJohn Marino 
327*e4b17023SJohn Marino #define VEC_safe_push(T,A,V,O)		\
328*e4b17023SJohn Marino 	(VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
329*e4b17023SJohn Marino 
330*e4b17023SJohn Marino /* Pop element off end
331*e4b17023SJohn Marino    T VEC_T_pop (VEC(T) *v);		// Integer
332*e4b17023SJohn Marino    T VEC_T_pop (VEC(T) *v);		// Pointer
333*e4b17023SJohn Marino    void VEC_T_pop (VEC(T) *v);		// Object
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino    Pop the last element off the end. Returns the element popped, for
336*e4b17023SJohn Marino    pointer vectors.  */
337*e4b17023SJohn Marino 
338*e4b17023SJohn Marino #define VEC_pop(T,V)	(VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO))
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino /* Truncate to specific length
341*e4b17023SJohn Marino    void VEC_T_truncate (VEC(T) *v, unsigned len);
342*e4b17023SJohn Marino 
343*e4b17023SJohn Marino    Set the length as specified.  The new length must be less than or
344*e4b17023SJohn Marino    equal to the current length.  This is an O(1) operation.  */
345*e4b17023SJohn Marino 
346*e4b17023SJohn Marino #define VEC_truncate(T,V,I)		\
347*e4b17023SJohn Marino 	(VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO))
348*e4b17023SJohn Marino 
349*e4b17023SJohn Marino /* Grow to a specific length.
350*e4b17023SJohn Marino    void VEC_T_A_safe_grow (VEC(T,A) *&v, int len);
351*e4b17023SJohn Marino 
352*e4b17023SJohn Marino    Grow the vector to a specific length.  The LEN must be as
353*e4b17023SJohn Marino    long or longer than the current length.  The new elements are
354*e4b17023SJohn Marino    uninitialized.  */
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino #define VEC_safe_grow(T,A,V,I)		\
357*e4b17023SJohn Marino 	(VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))
358*e4b17023SJohn Marino 
359*e4b17023SJohn Marino /* Grow to a specific length.
360*e4b17023SJohn Marino    void VEC_T_A_safe_grow_cleared (VEC(T,A) *&v, int len);
361*e4b17023SJohn Marino 
362*e4b17023SJohn Marino    Grow the vector to a specific length.  The LEN must be as
363*e4b17023SJohn Marino    long or longer than the current length.  The new elements are
364*e4b17023SJohn Marino    initialized to zero.  */
365*e4b17023SJohn Marino 
366*e4b17023SJohn Marino #define VEC_safe_grow_cleared(T,A,V,I)		\
367*e4b17023SJohn Marino 	(VEC_OP(T,A,safe_grow_cleared)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))
368*e4b17023SJohn Marino 
369*e4b17023SJohn Marino /* Replace element
370*e4b17023SJohn Marino    T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
371*e4b17023SJohn Marino    T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
372*e4b17023SJohn Marino    T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val);  // Object
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino    Replace the IXth element of V with a new value, VAL.  For pointer
375*e4b17023SJohn Marino    vectors returns the original value. For object vectors returns a
376*e4b17023SJohn Marino    pointer to the new value.  For object vectors the new value can be
377*e4b17023SJohn Marino    NULL, in which case no overwriting of the slot is actually
378*e4b17023SJohn Marino    performed.  */
379*e4b17023SJohn Marino 
380*e4b17023SJohn Marino #define VEC_replace(T,V,I,O)		\
381*e4b17023SJohn Marino 	(VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino /* Insert object with no reallocation
384*e4b17023SJohn Marino    T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
385*e4b17023SJohn Marino    T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
386*e4b17023SJohn Marino    T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
387*e4b17023SJohn Marino 
388*e4b17023SJohn Marino    Insert an element, VAL, at the IXth position of V. Return a pointer
389*e4b17023SJohn Marino    to the slot created.  For vectors of object, the new value can be
390*e4b17023SJohn Marino    NULL, in which case no initialization of the inserted slot takes
391*e4b17023SJohn Marino    place. There must be sufficient space.  */
392*e4b17023SJohn Marino 
393*e4b17023SJohn Marino #define VEC_quick_insert(T,V,I,O)	\
394*e4b17023SJohn Marino 	(VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino /* Insert object with reallocation
397*e4b17023SJohn Marino    T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
398*e4b17023SJohn Marino    T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
399*e4b17023SJohn Marino    T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino    Insert an element, VAL, at the IXth position of V. Return a pointer
402*e4b17023SJohn Marino    to the slot created.  For vectors of object, the new value can be
403*e4b17023SJohn Marino    NULL, in which case no initialization of the inserted slot takes
404*e4b17023SJohn Marino    place. Reallocate V, if necessary.  */
405*e4b17023SJohn Marino 
406*e4b17023SJohn Marino #define VEC_safe_insert(T,A,V,I,O)	\
407*e4b17023SJohn Marino 	(VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
408*e4b17023SJohn Marino 
409*e4b17023SJohn Marino /* Remove element retaining order
410*e4b17023SJohn Marino    T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
411*e4b17023SJohn Marino    T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
412*e4b17023SJohn Marino    void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
413*e4b17023SJohn Marino 
414*e4b17023SJohn Marino    Remove an element from the IXth position of V. Ordering of
415*e4b17023SJohn Marino    remaining elements is preserved.  For pointer vectors returns the
416*e4b17023SJohn Marino    removed object.  This is an O(N) operation due to a memmove.  */
417*e4b17023SJohn Marino 
418*e4b17023SJohn Marino #define VEC_ordered_remove(T,V,I)	\
419*e4b17023SJohn Marino 	(VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
420*e4b17023SJohn Marino 
421*e4b17023SJohn Marino /* Remove element destroying order
422*e4b17023SJohn Marino    T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
423*e4b17023SJohn Marino    T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
424*e4b17023SJohn Marino    void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino    Remove an element from the IXth position of V. Ordering of
427*e4b17023SJohn Marino    remaining elements is destroyed.  For pointer vectors returns the
428*e4b17023SJohn Marino    removed object.  This is an O(1) operation.  */
429*e4b17023SJohn Marino 
430*e4b17023SJohn Marino #define VEC_unordered_remove(T,V,I)	\
431*e4b17023SJohn Marino 	(VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino /* Remove a block of elements
434*e4b17023SJohn Marino    void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
435*e4b17023SJohn Marino 
436*e4b17023SJohn Marino    Remove LEN elements starting at the IXth.  Ordering is retained.
437*e4b17023SJohn Marino    This is an O(N) operation due to memmove.  */
438*e4b17023SJohn Marino 
439*e4b17023SJohn Marino #define VEC_block_remove(T,V,I,L)	\
440*e4b17023SJohn Marino 	(VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO))
441*e4b17023SJohn Marino 
442*e4b17023SJohn Marino /* Get the address of the array of elements
443*e4b17023SJohn Marino    T *VEC_T_address (VEC(T) v)
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino    If you need to directly manipulate the array (for instance, you
446*e4b17023SJohn Marino    want to feed it to qsort), use this accessor.  */
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino #define VEC_address(T,V)		(VEC_OP(T,base,address)(VEC_BASE(V)))
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino /* Conveniently sort the contents of the vector with qsort.
451*e4b17023SJohn Marino    void VEC_qsort (VEC(T) *v, int (*cmp_func)(const void *, const void *))  */
452*e4b17023SJohn Marino 
453*e4b17023SJohn Marino #define VEC_qsort(T,V,CMP) qsort(VEC_address (T,V), VEC_length(T,V),	\
454*e4b17023SJohn Marino 				 sizeof (T), CMP)
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino /* Find the first index in the vector not less than the object.
457*e4b17023SJohn Marino    unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
458*e4b17023SJohn Marino                                bool (*lessthan) (const T, const T)); // Integer
459*e4b17023SJohn Marino    unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
460*e4b17023SJohn Marino                                bool (*lessthan) (const T, const T)); // Pointer
461*e4b17023SJohn Marino    unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
462*e4b17023SJohn Marino                                bool (*lessthan) (const T*, const T*)); // Object
463*e4b17023SJohn Marino 
464*e4b17023SJohn Marino    Find the first position in which VAL could be inserted without
465*e4b17023SJohn Marino    changing the ordering of V.  LESSTHAN is a function that returns
466*e4b17023SJohn Marino    true if the first argument is strictly less than the second.  */
467*e4b17023SJohn Marino 
468*e4b17023SJohn Marino #define VEC_lower_bound(T,V,O,LT)    \
469*e4b17023SJohn Marino        (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO))
470*e4b17023SJohn Marino 
471*e4b17023SJohn Marino /* Reallocate an array of elements with prefix.  */
472*e4b17023SJohn Marino extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
473*e4b17023SJohn Marino extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
474*e4b17023SJohn Marino extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
475*e4b17023SJohn Marino extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
476*e4b17023SJohn Marino 				     MEM_STAT_DECL);
477*e4b17023SJohn Marino extern void ggc_free (void *);
478*e4b17023SJohn Marino #define vec_gc_free(V) ggc_free (V)
479*e4b17023SJohn Marino extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
480*e4b17023SJohn Marino extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
481*e4b17023SJohn Marino extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
482*e4b17023SJohn Marino extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
483*e4b17023SJohn Marino 				       MEM_STAT_DECL);
484*e4b17023SJohn Marino extern void dump_vec_loc_statistics (void);
485*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
486*e4b17023SJohn Marino void vec_heap_free (void *);
487*e4b17023SJohn Marino #else
488*e4b17023SJohn Marino /* Avoid problems with frontends that #define free(x).  */
489*e4b17023SJohn Marino #define vec_heap_free(V) (free) (V)
490*e4b17023SJohn Marino #endif
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino #if ENABLE_CHECKING
493*e4b17023SJohn Marino #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
494*e4b17023SJohn Marino #define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_
495*e4b17023SJohn Marino #define VEC_CHECK_PASS ,file_,line_,function_
496*e4b17023SJohn Marino 
497*e4b17023SJohn Marino #define VEC_ASSERT(EXPR,OP,T,A) \
498*e4b17023SJohn Marino   (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
499*e4b17023SJohn Marino 
500*e4b17023SJohn Marino extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
501*e4b17023SJohn Marino      ATTRIBUTE_NORETURN;
502*e4b17023SJohn Marino #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
503*e4b17023SJohn Marino #else
504*e4b17023SJohn Marino #define VEC_CHECK_INFO
505*e4b17023SJohn Marino #define VEC_CHECK_DECL
506*e4b17023SJohn Marino #define VEC_CHECK_PASS
507*e4b17023SJohn Marino #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
508*e4b17023SJohn Marino #endif
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino /* Note: gengtype has hardwired knowledge of the expansions of the
511*e4b17023SJohn Marino    VEC, DEF_VEC_*, and DEF_VEC_ALLOC_* macros.  If you change the
512*e4b17023SJohn Marino    expansions of these macros you may need to change gengtype too.  */
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino typedef struct GTY(()) vec_prefix
515*e4b17023SJohn Marino {
516*e4b17023SJohn Marino   unsigned num;
517*e4b17023SJohn Marino   unsigned alloc;
518*e4b17023SJohn Marino } vec_prefix;
519*e4b17023SJohn Marino 
520*e4b17023SJohn Marino #define VEC(T,A) VEC_##T##_##A
521*e4b17023SJohn Marino #define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP
522*e4b17023SJohn Marino 
523*e4b17023SJohn Marino /* Base of vector type, not user visible.  */
524*e4b17023SJohn Marino #define VEC_T(T,B)							  \
525*e4b17023SJohn Marino typedef struct VEC(T,B) 				 		  \
526*e4b17023SJohn Marino {									  \
527*e4b17023SJohn Marino   struct vec_prefix prefix;						  \
528*e4b17023SJohn Marino   T vec[1];								  \
529*e4b17023SJohn Marino } VEC(T,B)
530*e4b17023SJohn Marino 
531*e4b17023SJohn Marino #define VEC_T_GTY(T,B)							  \
532*e4b17023SJohn Marino typedef struct GTY(()) VEC(T,B)				 		  \
533*e4b17023SJohn Marino {									  \
534*e4b17023SJohn Marino   struct vec_prefix prefix;						  \
535*e4b17023SJohn Marino   T GTY ((length ("%h.prefix.num"))) vec[1];				  \
536*e4b17023SJohn Marino } VEC(T,B)
537*e4b17023SJohn Marino 
538*e4b17023SJohn Marino /* Derived vector type, user visible.  */
539*e4b17023SJohn Marino #define VEC_TA_GTY(T,B,A,GTY)						  \
540*e4b17023SJohn Marino typedef struct GTY VEC(T,A)						  \
541*e4b17023SJohn Marino {									  \
542*e4b17023SJohn Marino   VEC(T,B) base;							  \
543*e4b17023SJohn Marino } VEC(T,A)
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino #define VEC_TA(T,B,A)							  \
546*e4b17023SJohn Marino typedef struct VEC(T,A)							  \
547*e4b17023SJohn Marino {									  \
548*e4b17023SJohn Marino   VEC(T,B) base;							  \
549*e4b17023SJohn Marino } VEC(T,A)
550*e4b17023SJohn Marino 
551*e4b17023SJohn Marino /* Convert to base type.  */
552*e4b17023SJohn Marino #if GCC_VERSION >= 4000
553*e4b17023SJohn Marino #define VEC_BASE(P) \
554*e4b17023SJohn Marino   ((offsetof (__typeof (*P), base) == 0 || (P)) ? &(P)->base : 0)
555*e4b17023SJohn Marino #else
556*e4b17023SJohn Marino #define VEC_BASE(P)  ((P) ? &(P)->base : 0)
557*e4b17023SJohn Marino #endif
558*e4b17023SJohn Marino 
559*e4b17023SJohn Marino /* Vector of integer-like object.  */
560*e4b17023SJohn Marino #define DEF_VEC_I(T)							  \
561*e4b17023SJohn Marino static inline void VEC_OP (T,must_be,integral_type) (void) 		  \
562*e4b17023SJohn Marino {									  \
563*e4b17023SJohn Marino   (void)~(T)0;								  \
564*e4b17023SJohn Marino }									  \
565*e4b17023SJohn Marino 									  \
566*e4b17023SJohn Marino VEC_T(T,base);								  \
567*e4b17023SJohn Marino VEC_TA(T,base,none);							  \
568*e4b17023SJohn Marino DEF_VEC_FUNC_P(T)							  \
569*e4b17023SJohn Marino struct vec_swallow_trailing_semi
570*e4b17023SJohn Marino #define DEF_VEC_ALLOC_I(T,A)						  \
571*e4b17023SJohn Marino VEC_TA(T,base,A);							  \
572*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_I(T,A)						  \
573*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_I(T,A)						  \
574*e4b17023SJohn Marino struct vec_swallow_trailing_semi
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino /* Vector of pointer to object.  */
577*e4b17023SJohn Marino #define DEF_VEC_P(T) 							  \
578*e4b17023SJohn Marino static inline void VEC_OP (T,must_be,pointer_type) (void) 		  \
579*e4b17023SJohn Marino {									  \
580*e4b17023SJohn Marino   (void)((T)1 == (void *)1);						  \
581*e4b17023SJohn Marino }									  \
582*e4b17023SJohn Marino 									  \
583*e4b17023SJohn Marino VEC_T_GTY(T,base);							  \
584*e4b17023SJohn Marino VEC_TA(T,base,none);							  \
585*e4b17023SJohn Marino DEF_VEC_FUNC_P(T)							  \
586*e4b17023SJohn Marino struct vec_swallow_trailing_semi
587*e4b17023SJohn Marino #define DEF_VEC_ALLOC_P(T,A)						  \
588*e4b17023SJohn Marino VEC_TA(T,base,A);							  \
589*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_P(T,A)						  \
590*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_P(T,A)						  \
591*e4b17023SJohn Marino struct vec_swallow_trailing_semi
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino #define DEF_VEC_FUNC_P(T)						  \
594*e4b17023SJohn Marino static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)   \
595*e4b17023SJohn Marino {									  \
596*e4b17023SJohn Marino   return vec_ ? vec_->prefix.num : 0;						  \
597*e4b17023SJohn Marino }									  \
598*e4b17023SJohn Marino 									  \
599*e4b17023SJohn Marino static inline T VEC_OP (T,base,last)					  \
600*e4b17023SJohn Marino      (const VEC(T,base) *vec_ VEC_CHECK_DECL)				  \
601*e4b17023SJohn Marino {									  \
602*e4b17023SJohn Marino   VEC_ASSERT (vec_ && vec_->prefix.num, "last", T, base);			  \
603*e4b17023SJohn Marino   									  \
604*e4b17023SJohn Marino   return vec_->vec[vec_->prefix.num - 1];					  \
605*e4b17023SJohn Marino }									  \
606*e4b17023SJohn Marino 									  \
607*e4b17023SJohn Marino static inline T VEC_OP (T,base,index)					  \
608*e4b17023SJohn Marino      (const VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)		  \
609*e4b17023SJohn Marino {									  \
610*e4b17023SJohn Marino   VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base);		  \
611*e4b17023SJohn Marino   									  \
612*e4b17023SJohn Marino   return vec_->vec[ix_];						  \
613*e4b17023SJohn Marino }									  \
614*e4b17023SJohn Marino 									  \
615*e4b17023SJohn Marino static inline int VEC_OP (T,base,iterate)			  	  \
616*e4b17023SJohn Marino      (const VEC(T,base) *vec_, unsigned ix_, T *ptr)			  \
617*e4b17023SJohn Marino {									  \
618*e4b17023SJohn Marino   if (vec_ && ix_ < vec_->prefix.num)						  \
619*e4b17023SJohn Marino     {									  \
620*e4b17023SJohn Marino       *ptr = vec_->vec[ix_];						  \
621*e4b17023SJohn Marino       return 1;								  \
622*e4b17023SJohn Marino     }									  \
623*e4b17023SJohn Marino   else									  \
624*e4b17023SJohn Marino     {									  \
625*e4b17023SJohn Marino       *ptr = (T) 0;							  \
626*e4b17023SJohn Marino       return 0;								  \
627*e4b17023SJohn Marino     }									  \
628*e4b17023SJohn Marino }									  \
629*e4b17023SJohn Marino 									  \
630*e4b17023SJohn Marino static inline size_t VEC_OP (T,base,embedded_size)			  \
631*e4b17023SJohn Marino      (int alloc_)							  \
632*e4b17023SJohn Marino {									  \
633*e4b17023SJohn Marino   return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);		  \
634*e4b17023SJohn Marino }									  \
635*e4b17023SJohn Marino 									  \
636*e4b17023SJohn Marino static inline void VEC_OP (T,base,embedded_init)			  \
637*e4b17023SJohn Marino      (VEC(T,base) *vec_, int alloc_)					  \
638*e4b17023SJohn Marino {									  \
639*e4b17023SJohn Marino   vec_->prefix.num = 0;							  \
640*e4b17023SJohn Marino   vec_->prefix.alloc = alloc_;							  \
641*e4b17023SJohn Marino }									  \
642*e4b17023SJohn Marino 									  \
643*e4b17023SJohn Marino static inline int VEC_OP (T,base,space)	       				  \
644*e4b17023SJohn Marino      (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)			  \
645*e4b17023SJohn Marino {									  \
646*e4b17023SJohn Marino   VEC_ASSERT (alloc_ >= 0, "space", T, base);				  \
647*e4b17023SJohn Marino   return vec_ ? vec_->prefix.alloc - vec_->prefix.num >= (unsigned)alloc_ : !alloc_;	  \
648*e4b17023SJohn Marino }									  \
649*e4b17023SJohn Marino 									  \
650*e4b17023SJohn Marino static inline void VEC_OP(T,base,splice)				  \
651*e4b17023SJohn Marino      (VEC(T,base) *dst_, VEC(T,base) *src_ VEC_CHECK_DECL)		  \
652*e4b17023SJohn Marino {									  \
653*e4b17023SJohn Marino   if (src_)								  \
654*e4b17023SJohn Marino     {									  \
655*e4b17023SJohn Marino       unsigned len_ = src_->prefix.num;					  \
656*e4b17023SJohn Marino       VEC_ASSERT (dst_->prefix.num + len_ <= dst_->prefix.alloc, "splice", T, base);	  \
657*e4b17023SJohn Marino 									  \
658*e4b17023SJohn Marino       memcpy (&dst_->vec[dst_->prefix.num], &src_->vec[0], len_ * sizeof (T));	  \
659*e4b17023SJohn Marino       dst_->prefix.num += len_;						  \
660*e4b17023SJohn Marino     }									  \
661*e4b17023SJohn Marino }									  \
662*e4b17023SJohn Marino 									  \
663*e4b17023SJohn Marino static inline T *VEC_OP (T,base,quick_push)				  \
664*e4b17023SJohn Marino      (VEC(T,base) *vec_, T obj_ VEC_CHECK_DECL)				  \
665*e4b17023SJohn Marino {									  \
666*e4b17023SJohn Marino   T *slot_;								  \
667*e4b17023SJohn Marino   									  \
668*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base);		  \
669*e4b17023SJohn Marino   slot_ = &vec_->vec[vec_->prefix.num++];					  \
670*e4b17023SJohn Marino   *slot_ = obj_;							  \
671*e4b17023SJohn Marino   									  \
672*e4b17023SJohn Marino   return slot_;								  \
673*e4b17023SJohn Marino }									  \
674*e4b17023SJohn Marino 									  \
675*e4b17023SJohn Marino static inline T VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL)	  \
676*e4b17023SJohn Marino {									  \
677*e4b17023SJohn Marino   T obj_;								  \
678*e4b17023SJohn Marino 									  \
679*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num, "pop", T, base);				  \
680*e4b17023SJohn Marino   obj_ = vec_->vec[--vec_->prefix.num];					  \
681*e4b17023SJohn Marino 									  \
682*e4b17023SJohn Marino   return obj_;								  \
683*e4b17023SJohn Marino }									  \
684*e4b17023SJohn Marino 									  \
685*e4b17023SJohn Marino static inline void VEC_OP (T,base,truncate)				  \
686*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)			  \
687*e4b17023SJohn Marino {									  \
688*e4b17023SJohn Marino   VEC_ASSERT (vec_ ? vec_->prefix.num >= size_ : !size_, "truncate", T, base);	  \
689*e4b17023SJohn Marino   if (vec_)								  \
690*e4b17023SJohn Marino     vec_->prefix.num = size_;							  \
691*e4b17023SJohn Marino }									  \
692*e4b17023SJohn Marino 									  \
693*e4b17023SJohn Marino static inline T VEC_OP (T,base,replace)		  	     		  \
694*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)		  \
695*e4b17023SJohn Marino {									  \
696*e4b17023SJohn Marino   T old_obj_;								  \
697*e4b17023SJohn Marino 									  \
698*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "replace", T, base);			  \
699*e4b17023SJohn Marino   old_obj_ = vec_->vec[ix_];						  \
700*e4b17023SJohn Marino   vec_->vec[ix_] = obj_;						  \
701*e4b17023SJohn Marino 									  \
702*e4b17023SJohn Marino   return old_obj_;							  \
703*e4b17023SJohn Marino }									  \
704*e4b17023SJohn Marino 									  \
705*e4b17023SJohn Marino static inline T *VEC_OP (T,base,quick_insert)				  \
706*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)		  \
707*e4b17023SJohn Marino {									  \
708*e4b17023SJohn Marino   T *slot_;								  \
709*e4b17023SJohn Marino 									  \
710*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base);		  \
711*e4b17023SJohn Marino   VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base);			  \
712*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
713*e4b17023SJohn Marino   memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T));		  \
714*e4b17023SJohn Marino   *slot_ = obj_;							  \
715*e4b17023SJohn Marino   									  \
716*e4b17023SJohn Marino   return slot_;								  \
717*e4b17023SJohn Marino }									  \
718*e4b17023SJohn Marino 									  \
719*e4b17023SJohn Marino static inline T VEC_OP (T,base,ordered_remove)				  \
720*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
721*e4b17023SJohn Marino {									  \
722*e4b17023SJohn Marino   T *slot_;								  \
723*e4b17023SJohn Marino   T obj_;								  \
724*e4b17023SJohn Marino 									  \
725*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base);			  \
726*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
727*e4b17023SJohn Marino   obj_ = *slot_;							  \
728*e4b17023SJohn Marino   memmove (slot_, slot_ + 1, (--vec_->prefix.num - ix_) * sizeof (T));     	  \
729*e4b17023SJohn Marino 									  \
730*e4b17023SJohn Marino   return obj_;								  \
731*e4b17023SJohn Marino }									  \
732*e4b17023SJohn Marino 									  \
733*e4b17023SJohn Marino static inline T VEC_OP (T,base,unordered_remove)			  \
734*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
735*e4b17023SJohn Marino {									  \
736*e4b17023SJohn Marino   T *slot_;								  \
737*e4b17023SJohn Marino   T obj_;								  \
738*e4b17023SJohn Marino 									  \
739*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base);			  \
740*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
741*e4b17023SJohn Marino   obj_ = *slot_;							  \
742*e4b17023SJohn Marino   *slot_ = vec_->vec[--vec_->prefix.num];					  \
743*e4b17023SJohn Marino 									  \
744*e4b17023SJohn Marino   return obj_;								  \
745*e4b17023SJohn Marino }									  \
746*e4b17023SJohn Marino 									  \
747*e4b17023SJohn Marino static inline void VEC_OP (T,base,block_remove)				  \
748*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)	  \
749*e4b17023SJohn Marino {									  \
750*e4b17023SJohn Marino   T *slot_;								  \
751*e4b17023SJohn Marino 									  \
752*e4b17023SJohn Marino   VEC_ASSERT (ix_ + len_ <= vec_->prefix.num, "block_remove", T, base);	  \
753*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
754*e4b17023SJohn Marino   vec_->prefix.num -= len_;							  \
755*e4b17023SJohn Marino   memmove (slot_, slot_ + len_, (vec_->prefix.num - ix_) * sizeof (T));	  \
756*e4b17023SJohn Marino }									  \
757*e4b17023SJohn Marino 									  \
758*e4b17023SJohn Marino static inline T *VEC_OP (T,base,address)				  \
759*e4b17023SJohn Marino      (VEC(T,base) *vec_)						  \
760*e4b17023SJohn Marino {									  \
761*e4b17023SJohn Marino   return vec_ ? vec_->vec : 0;						  \
762*e4b17023SJohn Marino }									  \
763*e4b17023SJohn Marino 									  \
764*e4b17023SJohn Marino static inline unsigned VEC_OP (T,base,lower_bound)			  \
765*e4b17023SJohn Marino      (VEC(T,base) *vec_, const T obj_,					  \
766*e4b17023SJohn Marino       bool (*lessthan_)(const T, const T) VEC_CHECK_DECL)		  \
767*e4b17023SJohn Marino {									  \
768*e4b17023SJohn Marino    unsigned int len_ = VEC_OP (T,base, length) (vec_);			  \
769*e4b17023SJohn Marino    unsigned int half_, middle_;						  \
770*e4b17023SJohn Marino    unsigned int first_ = 0;						  \
771*e4b17023SJohn Marino    while (len_ > 0)							  \
772*e4b17023SJohn Marino      {									  \
773*e4b17023SJohn Marino         T middle_elem_;							  \
774*e4b17023SJohn Marino         half_ = len_ >> 1;						  \
775*e4b17023SJohn Marino         middle_ = first_;						  \
776*e4b17023SJohn Marino         middle_ += half_;						  \
777*e4b17023SJohn Marino         middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
778*e4b17023SJohn Marino         if (lessthan_ (middle_elem_, obj_))				  \
779*e4b17023SJohn Marino           {								  \
780*e4b17023SJohn Marino              first_ = middle_;						  \
781*e4b17023SJohn Marino              ++first_;							  \
782*e4b17023SJohn Marino              len_ = len_ - half_ - 1;					  \
783*e4b17023SJohn Marino           }								  \
784*e4b17023SJohn Marino         else								  \
785*e4b17023SJohn Marino           len_ = half_;							  \
786*e4b17023SJohn Marino      }									  \
787*e4b17023SJohn Marino    return first_;							  \
788*e4b17023SJohn Marino }
789*e4b17023SJohn Marino 
790*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_P(T,A)					  \
791*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,alloc)				  \
792*e4b17023SJohn Marino      (int alloc_ MEM_STAT_DECL)						  \
793*e4b17023SJohn Marino {									  \
794*e4b17023SJohn Marino   return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_		  \
795*e4b17023SJohn Marino 						 PASS_MEM_STAT);	  \
796*e4b17023SJohn Marino }
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino 
799*e4b17023SJohn Marino #define DEF_VEC_NONALLOC_FUNCS_P(T,A)					  \
800*e4b17023SJohn Marino static inline void VEC_OP (T,A,free)					  \
801*e4b17023SJohn Marino      (VEC(T,A) **vec_)							  \
802*e4b17023SJohn Marino {									  \
803*e4b17023SJohn Marino   if (*vec_)								  \
804*e4b17023SJohn Marino     vec_##A##_free (*vec_);						  \
805*e4b17023SJohn Marino   *vec_ = NULL;								  \
806*e4b17023SJohn Marino }									  \
807*e4b17023SJohn Marino 									  \
808*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
809*e4b17023SJohn Marino {									  \
810*e4b17023SJohn Marino   size_t len_ = vec_ ? vec_->prefix.num : 0;					  \
811*e4b17023SJohn Marino   VEC (T,A) *new_vec_ = NULL;						  \
812*e4b17023SJohn Marino 									  \
813*e4b17023SJohn Marino   if (len_)								  \
814*e4b17023SJohn Marino     {									  \
815*e4b17023SJohn Marino       new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact		  \
816*e4b17023SJohn Marino 			       (NULL, len_ PASS_MEM_STAT));		  \
817*e4b17023SJohn Marino 									  \
818*e4b17023SJohn Marino       new_vec_->base.prefix.num = len_;					  \
819*e4b17023SJohn Marino       memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
820*e4b17023SJohn Marino     }									  \
821*e4b17023SJohn Marino   return new_vec_;							  \
822*e4b17023SJohn Marino }									  \
823*e4b17023SJohn Marino 									  \
824*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve)	       				  \
825*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
826*e4b17023SJohn Marino {									  \
827*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
828*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
829*e4b17023SJohn Marino 		  							  \
830*e4b17023SJohn Marino   if (extend)	  							  \
831*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \
832*e4b17023SJohn Marino 		  							  \
833*e4b17023SJohn Marino   return extend;							  \
834*e4b17023SJohn Marino }									  \
835*e4b17023SJohn Marino 									  \
836*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve_exact)  				  \
837*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
838*e4b17023SJohn Marino {									  \
839*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
840*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
841*e4b17023SJohn Marino 		  							  \
842*e4b17023SJohn Marino   if (extend)	  							  \
843*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_	  \
844*e4b17023SJohn Marino 						    PASS_MEM_STAT);	  \
845*e4b17023SJohn Marino 		  							  \
846*e4b17023SJohn Marino   return extend;							  \
847*e4b17023SJohn Marino }									  \
848*e4b17023SJohn Marino 									  \
849*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow)				  \
850*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
851*e4b17023SJohn Marino {									  \
852*e4b17023SJohn Marino   VEC_ASSERT (size_ >= 0						  \
853*e4b17023SJohn Marino 	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
854*e4b17023SJohn Marino 						 "grow", T, A);		  \
855*e4b17023SJohn Marino   VEC_OP (T,A,reserve_exact) (vec_,					  \
856*e4b17023SJohn Marino 			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \
857*e4b17023SJohn Marino 			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
858*e4b17023SJohn Marino   VEC_BASE (*vec_)->prefix.num = size_;					  \
859*e4b17023SJohn Marino }									  \
860*e4b17023SJohn Marino 									  \
861*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow_cleared)			  \
862*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
863*e4b17023SJohn Marino {									  \
864*e4b17023SJohn Marino   int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
865*e4b17023SJohn Marino   VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
866*e4b17023SJohn Marino   memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
867*e4b17023SJohn Marino 	  sizeof (T) * (size_ - oldsize));				  \
868*e4b17023SJohn Marino }									  \
869*e4b17023SJohn Marino 									  \
870*e4b17023SJohn Marino static inline void VEC_OP(T,A,safe_splice)				  \
871*e4b17023SJohn Marino      (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
872*e4b17023SJohn Marino {									  \
873*e4b17023SJohn Marino   if (src_)								  \
874*e4b17023SJohn Marino     {									  \
875*e4b17023SJohn Marino       VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num			  \
876*e4b17023SJohn Marino 				  VEC_CHECK_PASS MEM_STAT_INFO);	  \
877*e4b17023SJohn Marino 									  \
878*e4b17023SJohn Marino       VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_			  \
879*e4b17023SJohn Marino 			      VEC_CHECK_PASS);				  \
880*e4b17023SJohn Marino     }									  \
881*e4b17023SJohn Marino }									  \
882*e4b17023SJohn Marino 									  \
883*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_push)					  \
884*e4b17023SJohn Marino      (VEC(T,A) **vec_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL)       	  \
885*e4b17023SJohn Marino {									  \
886*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
887*e4b17023SJohn Marino 									  \
888*e4b17023SJohn Marino   return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
889*e4b17023SJohn Marino }									  \
890*e4b17023SJohn Marino 									  \
891*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
892*e4b17023SJohn Marino      (VEC(T,A) **vec_, unsigned ix_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL)  \
893*e4b17023SJohn Marino {									  \
894*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
895*e4b17023SJohn Marino 									  \
896*e4b17023SJohn Marino   return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
897*e4b17023SJohn Marino  				       VEC_CHECK_PASS);			  \
898*e4b17023SJohn Marino }
899*e4b17023SJohn Marino 
900*e4b17023SJohn Marino /* Vector of object.  */
901*e4b17023SJohn Marino #define DEF_VEC_O(T)							  \
902*e4b17023SJohn Marino VEC_T_GTY(T,base);							  \
903*e4b17023SJohn Marino VEC_TA(T,base,none);						  \
904*e4b17023SJohn Marino DEF_VEC_FUNC_O(T)							  \
905*e4b17023SJohn Marino struct vec_swallow_trailing_semi
906*e4b17023SJohn Marino #define DEF_VEC_ALLOC_O(T,A)						  \
907*e4b17023SJohn Marino VEC_TA(T,base,A);							  \
908*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_O(T,A)						  \
909*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_O(T,A)						  \
910*e4b17023SJohn Marino struct vec_swallow_trailing_semi
911*e4b17023SJohn Marino 
912*e4b17023SJohn Marino #define DEF_VEC_FUNC_O(T)						  \
913*e4b17023SJohn Marino static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)	  \
914*e4b17023SJohn Marino {									  \
915*e4b17023SJohn Marino   return vec_ ? vec_->prefix.num : 0;						  \
916*e4b17023SJohn Marino }									  \
917*e4b17023SJohn Marino 									  \
918*e4b17023SJohn Marino static inline T *VEC_OP (T,base,last) (VEC(T,base) *vec_ VEC_CHECK_DECL)  \
919*e4b17023SJohn Marino {									  \
920*e4b17023SJohn Marino   VEC_ASSERT (vec_ && vec_->prefix.num, "last", T, base);			  \
921*e4b17023SJohn Marino   									  \
922*e4b17023SJohn Marino   return &vec_->vec[vec_->prefix.num - 1];					  \
923*e4b17023SJohn Marino }									  \
924*e4b17023SJohn Marino 									  \
925*e4b17023SJohn Marino static inline T *VEC_OP (T,base,index)					  \
926*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
927*e4b17023SJohn Marino {									  \
928*e4b17023SJohn Marino   VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base);		  \
929*e4b17023SJohn Marino   									  \
930*e4b17023SJohn Marino   return &vec_->vec[ix_];						  \
931*e4b17023SJohn Marino }									  \
932*e4b17023SJohn Marino 									  \
933*e4b17023SJohn Marino static inline int VEC_OP (T,base,iterate)			     	  \
934*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, T **ptr)				  \
935*e4b17023SJohn Marino {									  \
936*e4b17023SJohn Marino   if (vec_ && ix_ < vec_->prefix.num)						  \
937*e4b17023SJohn Marino     {									  \
938*e4b17023SJohn Marino       *ptr = &vec_->vec[ix_];						  \
939*e4b17023SJohn Marino       return 1;								  \
940*e4b17023SJohn Marino     }									  \
941*e4b17023SJohn Marino   else									  \
942*e4b17023SJohn Marino     {									  \
943*e4b17023SJohn Marino       *ptr = 0;								  \
944*e4b17023SJohn Marino       return 0;								  \
945*e4b17023SJohn Marino     }									  \
946*e4b17023SJohn Marino }									  \
947*e4b17023SJohn Marino 									  \
948*e4b17023SJohn Marino static inline size_t VEC_OP (T,base,embedded_size)			  \
949*e4b17023SJohn Marino      (int alloc_)							  \
950*e4b17023SJohn Marino {									  \
951*e4b17023SJohn Marino   return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);		  \
952*e4b17023SJohn Marino }									  \
953*e4b17023SJohn Marino 									  \
954*e4b17023SJohn Marino static inline void VEC_OP (T,base,embedded_init)			  \
955*e4b17023SJohn Marino      (VEC(T,base) *vec_, int alloc_)					  \
956*e4b17023SJohn Marino {									  \
957*e4b17023SJohn Marino   vec_->prefix.num = 0;							  \
958*e4b17023SJohn Marino   vec_->prefix.alloc = alloc_;							  \
959*e4b17023SJohn Marino }									  \
960*e4b17023SJohn Marino 									  \
961*e4b17023SJohn Marino static inline int VEC_OP (T,base,space)	       				  \
962*e4b17023SJohn Marino      (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)			  \
963*e4b17023SJohn Marino {									  \
964*e4b17023SJohn Marino   VEC_ASSERT (alloc_ >= 0, "space", T, base);				  \
965*e4b17023SJohn Marino   return vec_ ? vec_->prefix.alloc - vec_->prefix.num >= (unsigned)alloc_ : !alloc_;	  \
966*e4b17023SJohn Marino }									  \
967*e4b17023SJohn Marino 									  \
968*e4b17023SJohn Marino static inline void VEC_OP(T,base,splice)				  \
969*e4b17023SJohn Marino      (VEC(T,base) *dst_, VEC(T,base) *src_ VEC_CHECK_DECL)		  \
970*e4b17023SJohn Marino {									  \
971*e4b17023SJohn Marino   if (src_)								  \
972*e4b17023SJohn Marino     {									  \
973*e4b17023SJohn Marino       unsigned len_ = src_->prefix.num;					  \
974*e4b17023SJohn Marino       VEC_ASSERT (dst_->prefix.num + len_ <= dst_->prefix.alloc, "splice", T, base);	  \
975*e4b17023SJohn Marino 									  \
976*e4b17023SJohn Marino       memcpy (&dst_->vec[dst_->prefix.num], &src_->vec[0], len_ * sizeof (T));	  \
977*e4b17023SJohn Marino       dst_->prefix.num += len_;						  \
978*e4b17023SJohn Marino     }									  \
979*e4b17023SJohn Marino }									  \
980*e4b17023SJohn Marino 									  \
981*e4b17023SJohn Marino static inline T *VEC_OP (T,base,quick_push)				  \
982*e4b17023SJohn Marino      (VEC(T,base) *vec_, const T *obj_ VEC_CHECK_DECL)			  \
983*e4b17023SJohn Marino {									  \
984*e4b17023SJohn Marino   T *slot_;								  \
985*e4b17023SJohn Marino   									  \
986*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base);		  \
987*e4b17023SJohn Marino   slot_ = &vec_->vec[vec_->prefix.num++];					  \
988*e4b17023SJohn Marino   if (obj_)								  \
989*e4b17023SJohn Marino     *slot_ = *obj_;							  \
990*e4b17023SJohn Marino   									  \
991*e4b17023SJohn Marino   return slot_;								  \
992*e4b17023SJohn Marino }									  \
993*e4b17023SJohn Marino 									  \
994*e4b17023SJohn Marino static inline void VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
995*e4b17023SJohn Marino {									  \
996*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num, "pop", T, base);				  \
997*e4b17023SJohn Marino   --vec_->prefix.num;								  \
998*e4b17023SJohn Marino }									  \
999*e4b17023SJohn Marino 									  \
1000*e4b17023SJohn Marino static inline void VEC_OP (T,base,truncate)				  \
1001*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)			  \
1002*e4b17023SJohn Marino {									  \
1003*e4b17023SJohn Marino   VEC_ASSERT (vec_ ? vec_->prefix.num >= size_ : !size_, "truncate", T, base);	  \
1004*e4b17023SJohn Marino   if (vec_)								  \
1005*e4b17023SJohn Marino     vec_->prefix.num = size_;							  \
1006*e4b17023SJohn Marino }									  \
1007*e4b17023SJohn Marino 									  \
1008*e4b17023SJohn Marino static inline T *VEC_OP (T,base,replace)				  \
1009*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)	  \
1010*e4b17023SJohn Marino {									  \
1011*e4b17023SJohn Marino   T *slot_;								  \
1012*e4b17023SJohn Marino 									  \
1013*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "replace", T, base);			  \
1014*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
1015*e4b17023SJohn Marino   if (obj_)								  \
1016*e4b17023SJohn Marino     *slot_ = *obj_;							  \
1017*e4b17023SJohn Marino 									  \
1018*e4b17023SJohn Marino   return slot_;								  \
1019*e4b17023SJohn Marino }									  \
1020*e4b17023SJohn Marino 									  \
1021*e4b17023SJohn Marino static inline T *VEC_OP (T,base,quick_insert)				  \
1022*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)	  \
1023*e4b17023SJohn Marino {									  \
1024*e4b17023SJohn Marino   T *slot_;								  \
1025*e4b17023SJohn Marino 									  \
1026*e4b17023SJohn Marino   VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base);		  \
1027*e4b17023SJohn Marino   VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base);			  \
1028*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
1029*e4b17023SJohn Marino   memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T));		  \
1030*e4b17023SJohn Marino   if (obj_)								  \
1031*e4b17023SJohn Marino     *slot_ = *obj_;							  \
1032*e4b17023SJohn Marino   									  \
1033*e4b17023SJohn Marino   return slot_;								  \
1034*e4b17023SJohn Marino }									  \
1035*e4b17023SJohn Marino 									  \
1036*e4b17023SJohn Marino static inline void VEC_OP (T,base,ordered_remove)			  \
1037*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
1038*e4b17023SJohn Marino {									  \
1039*e4b17023SJohn Marino   T *slot_;								  \
1040*e4b17023SJohn Marino 									  \
1041*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base);			  \
1042*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
1043*e4b17023SJohn Marino   memmove (slot_, slot_ + 1, (--vec_->prefix.num - ix_) * sizeof (T));		  \
1044*e4b17023SJohn Marino }									  \
1045*e4b17023SJohn Marino 									  \
1046*e4b17023SJohn Marino static inline void VEC_OP (T,base,unordered_remove)			  \
1047*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
1048*e4b17023SJohn Marino {									  \
1049*e4b17023SJohn Marino   VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base);			  \
1050*e4b17023SJohn Marino   vec_->vec[ix_] = vec_->vec[--vec_->prefix.num];				  \
1051*e4b17023SJohn Marino }									  \
1052*e4b17023SJohn Marino 									  \
1053*e4b17023SJohn Marino static inline void VEC_OP (T,base,block_remove)				  \
1054*e4b17023SJohn Marino      (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)	  \
1055*e4b17023SJohn Marino {									  \
1056*e4b17023SJohn Marino   T *slot_;								  \
1057*e4b17023SJohn Marino 									  \
1058*e4b17023SJohn Marino   VEC_ASSERT (ix_ + len_ <= vec_->prefix.num, "block_remove", T, base);	  \
1059*e4b17023SJohn Marino   slot_ = &vec_->vec[ix_];						  \
1060*e4b17023SJohn Marino   vec_->prefix.num -= len_;							  \
1061*e4b17023SJohn Marino   memmove (slot_, slot_ + len_, (vec_->prefix.num - ix_) * sizeof (T));	  \
1062*e4b17023SJohn Marino }									  \
1063*e4b17023SJohn Marino 									  \
1064*e4b17023SJohn Marino static inline T *VEC_OP (T,base,address)				  \
1065*e4b17023SJohn Marino      (VEC(T,base) *vec_)						  \
1066*e4b17023SJohn Marino {									  \
1067*e4b17023SJohn Marino   return vec_ ? vec_->vec : 0;						  \
1068*e4b17023SJohn Marino }									  \
1069*e4b17023SJohn Marino 									  \
1070*e4b17023SJohn Marino static inline unsigned VEC_OP (T,base,lower_bound)			  \
1071*e4b17023SJohn Marino      (VEC(T,base) *vec_, const T *obj_,					  \
1072*e4b17023SJohn Marino       bool (*lessthan_)(const T *, const T *) VEC_CHECK_DECL)		  \
1073*e4b17023SJohn Marino {									  \
1074*e4b17023SJohn Marino    unsigned int len_ = VEC_OP (T, base, length) (vec_);			  \
1075*e4b17023SJohn Marino    unsigned int half_, middle_;						  \
1076*e4b17023SJohn Marino    unsigned int first_ = 0;						  \
1077*e4b17023SJohn Marino    while (len_ > 0)							  \
1078*e4b17023SJohn Marino      {									  \
1079*e4b17023SJohn Marino         T *middle_elem_;						  \
1080*e4b17023SJohn Marino         half_ = len_ >> 1;						  \
1081*e4b17023SJohn Marino         middle_ = first_;						  \
1082*e4b17023SJohn Marino         middle_ += half_;						  \
1083*e4b17023SJohn Marino         middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
1084*e4b17023SJohn Marino         if (lessthan_ (middle_elem_, obj_))				  \
1085*e4b17023SJohn Marino           {								  \
1086*e4b17023SJohn Marino              first_ = middle_;						  \
1087*e4b17023SJohn Marino              ++first_;							  \
1088*e4b17023SJohn Marino              len_ = len_ - half_ - 1;					  \
1089*e4b17023SJohn Marino           }								  \
1090*e4b17023SJohn Marino         else								  \
1091*e4b17023SJohn Marino           len_ = half_;							  \
1092*e4b17023SJohn Marino      }									  \
1093*e4b17023SJohn Marino    return first_;							  \
1094*e4b17023SJohn Marino }
1095*e4b17023SJohn Marino 
1096*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_O(T,A)					  \
1097*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,alloc)      			  \
1098*e4b17023SJohn Marino      (int alloc_ MEM_STAT_DECL)						  \
1099*e4b17023SJohn Marino {									  \
1100*e4b17023SJohn Marino   return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_,		  \
1101*e4b17023SJohn Marino 						 offsetof (VEC(T,A),base.vec), \
1102*e4b17023SJohn Marino 						 sizeof (T)		  \
1103*e4b17023SJohn Marino 						 PASS_MEM_STAT);	  \
1104*e4b17023SJohn Marino }
1105*e4b17023SJohn Marino 
1106*e4b17023SJohn Marino #define DEF_VEC_NONALLOC_FUNCS_O(T,A)					  \
1107*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
1108*e4b17023SJohn Marino {									  \
1109*e4b17023SJohn Marino   size_t len_ = vec_ ? vec_->prefix.num : 0;					  \
1110*e4b17023SJohn Marino   VEC (T,A) *new_vec_ = NULL;						  \
1111*e4b17023SJohn Marino 									  \
1112*e4b17023SJohn Marino   if (len_)								  \
1113*e4b17023SJohn Marino     {									  \
1114*e4b17023SJohn Marino       new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact		  \
1115*e4b17023SJohn Marino 			       (NULL, len_,				  \
1116*e4b17023SJohn Marino 				offsetof (VEC(T,A),base.vec), sizeof (T)  \
1117*e4b17023SJohn Marino 				PASS_MEM_STAT));			  \
1118*e4b17023SJohn Marino 									  \
1119*e4b17023SJohn Marino       new_vec_->base.prefix.num = len_;					  \
1120*e4b17023SJohn Marino       memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
1121*e4b17023SJohn Marino     }									  \
1122*e4b17023SJohn Marino   return new_vec_;							  \
1123*e4b17023SJohn Marino }									  \
1124*e4b17023SJohn Marino 									  \
1125*e4b17023SJohn Marino static inline void VEC_OP (T,A,free)					  \
1126*e4b17023SJohn Marino      (VEC(T,A) **vec_)							  \
1127*e4b17023SJohn Marino {									  \
1128*e4b17023SJohn Marino   if (*vec_)								  \
1129*e4b17023SJohn Marino     vec_##A##_free (*vec_);						  \
1130*e4b17023SJohn Marino   *vec_ = NULL;								  \
1131*e4b17023SJohn Marino }									  \
1132*e4b17023SJohn Marino 									  \
1133*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve)	   	    			  \
1134*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1135*e4b17023SJohn Marino {									  \
1136*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1137*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1138*e4b17023SJohn Marino 									  \
1139*e4b17023SJohn Marino   if (extend)								  \
1140*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,		  \
1141*e4b17023SJohn Marino 			   		      offsetof (VEC(T,A),base.vec),\
1142*e4b17023SJohn Marino  					      sizeof (T)		  \
1143*e4b17023SJohn Marino 			   		      PASS_MEM_STAT);		  \
1144*e4b17023SJohn Marino 									  \
1145*e4b17023SJohn Marino   return extend;							  \
1146*e4b17023SJohn Marino }									  \
1147*e4b17023SJohn Marino 									  \
1148*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve_exact)   	    			  \
1149*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1150*e4b17023SJohn Marino {									  \
1151*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1152*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1153*e4b17023SJohn Marino 									  \
1154*e4b17023SJohn Marino   if (extend)								  \
1155*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact			  \
1156*e4b17023SJohn Marino 			 (*vec_, alloc_,				  \
1157*e4b17023SJohn Marino 			  offsetof (VEC(T,A),base.vec),			  \
1158*e4b17023SJohn Marino 			  sizeof (T) PASS_MEM_STAT);			  \
1159*e4b17023SJohn Marino 									  \
1160*e4b17023SJohn Marino   return extend;							  \
1161*e4b17023SJohn Marino }									  \
1162*e4b17023SJohn Marino 									  \
1163*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow)				  \
1164*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1165*e4b17023SJohn Marino {									  \
1166*e4b17023SJohn Marino   VEC_ASSERT (size_ >= 0						  \
1167*e4b17023SJohn Marino 	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
1168*e4b17023SJohn Marino 						 "grow", T, A);		  \
1169*e4b17023SJohn Marino   VEC_OP (T,A,reserve_exact) (vec_,					  \
1170*e4b17023SJohn Marino 			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \
1171*e4b17023SJohn Marino 			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
1172*e4b17023SJohn Marino   VEC_BASE (*vec_)->prefix.num = size_;					  \
1173*e4b17023SJohn Marino }									  \
1174*e4b17023SJohn Marino 									  \
1175*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow_cleared)			  \
1176*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1177*e4b17023SJohn Marino {									  \
1178*e4b17023SJohn Marino   int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
1179*e4b17023SJohn Marino   VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
1180*e4b17023SJohn Marino   memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
1181*e4b17023SJohn Marino 	  sizeof (T) * (size_ - oldsize));				  \
1182*e4b17023SJohn Marino }									  \
1183*e4b17023SJohn Marino 									  \
1184*e4b17023SJohn Marino static inline void VEC_OP(T,A,safe_splice)				  \
1185*e4b17023SJohn Marino      (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
1186*e4b17023SJohn Marino {									  \
1187*e4b17023SJohn Marino   if (src_)								  \
1188*e4b17023SJohn Marino     {									  \
1189*e4b17023SJohn Marino       VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num			  \
1190*e4b17023SJohn Marino 				  VEC_CHECK_PASS MEM_STAT_INFO);	  \
1191*e4b17023SJohn Marino 									  \
1192*e4b17023SJohn Marino       VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_			  \
1193*e4b17023SJohn Marino 			      VEC_CHECK_PASS);				  \
1194*e4b17023SJohn Marino     }									  \
1195*e4b17023SJohn Marino }									  \
1196*e4b17023SJohn Marino 									  \
1197*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_push)					  \
1198*e4b17023SJohn Marino      (VEC(T,A) **vec_, const T *obj_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
1199*e4b17023SJohn Marino {									  \
1200*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
1201*e4b17023SJohn Marino 									  \
1202*e4b17023SJohn Marino   return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
1203*e4b17023SJohn Marino }									  \
1204*e4b17023SJohn Marino 									  \
1205*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
1206*e4b17023SJohn Marino      (VEC(T,A) **vec_, unsigned ix_, const T *obj_			  \
1207*e4b17023SJohn Marino  		VEC_CHECK_DECL MEM_STAT_DECL)				  \
1208*e4b17023SJohn Marino {									  \
1209*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
1210*e4b17023SJohn Marino 									  \
1211*e4b17023SJohn Marino   return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
1212*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1213*e4b17023SJohn Marino }
1214*e4b17023SJohn Marino 
1215*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_I(T,A)					  \
1216*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,alloc)      			  \
1217*e4b17023SJohn Marino      (int alloc_ MEM_STAT_DECL)						  \
1218*e4b17023SJohn Marino {									  \
1219*e4b17023SJohn Marino   return (VEC(T,A) *) vec_##A##_o_reserve_exact				  \
1220*e4b17023SJohn Marino 		      (NULL, alloc_, offsetof (VEC(T,A),base.vec),	  \
1221*e4b17023SJohn Marino 		       sizeof (T) PASS_MEM_STAT);			  \
1222*e4b17023SJohn Marino }
1223*e4b17023SJohn Marino 
1224*e4b17023SJohn Marino #define DEF_VEC_NONALLOC_FUNCS_I(T,A)					  \
1225*e4b17023SJohn Marino static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
1226*e4b17023SJohn Marino {									  \
1227*e4b17023SJohn Marino   size_t len_ = vec_ ? vec_->prefix.num : 0;					  \
1228*e4b17023SJohn Marino   VEC (T,A) *new_vec_ = NULL;						  \
1229*e4b17023SJohn Marino 									  \
1230*e4b17023SJohn Marino   if (len_)								  \
1231*e4b17023SJohn Marino     {									  \
1232*e4b17023SJohn Marino       new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact		  \
1233*e4b17023SJohn Marino 			       (NULL, len_,				  \
1234*e4b17023SJohn Marino 				offsetof (VEC(T,A),base.vec), sizeof (T)  \
1235*e4b17023SJohn Marino 				PASS_MEM_STAT));			  \
1236*e4b17023SJohn Marino 									  \
1237*e4b17023SJohn Marino       new_vec_->base.prefix.num = len_;					  \
1238*e4b17023SJohn Marino       memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
1239*e4b17023SJohn Marino     }									  \
1240*e4b17023SJohn Marino   return new_vec_;							  \
1241*e4b17023SJohn Marino }									  \
1242*e4b17023SJohn Marino 									  \
1243*e4b17023SJohn Marino static inline void VEC_OP (T,A,free)					  \
1244*e4b17023SJohn Marino      (VEC(T,A) **vec_)							  \
1245*e4b17023SJohn Marino {									  \
1246*e4b17023SJohn Marino   if (*vec_)								  \
1247*e4b17023SJohn Marino     vec_##A##_free (*vec_);						  \
1248*e4b17023SJohn Marino   *vec_ = NULL;								  \
1249*e4b17023SJohn Marino }									  \
1250*e4b17023SJohn Marino 									  \
1251*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve)	   	    			  \
1252*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1253*e4b17023SJohn Marino {									  \
1254*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1255*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1256*e4b17023SJohn Marino 									  \
1257*e4b17023SJohn Marino   if (extend)								  \
1258*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,		  \
1259*e4b17023SJohn Marino 			   		      offsetof (VEC(T,A),base.vec),\
1260*e4b17023SJohn Marino  					      sizeof (T)		  \
1261*e4b17023SJohn Marino 			   		      PASS_MEM_STAT);		  \
1262*e4b17023SJohn Marino 									  \
1263*e4b17023SJohn Marino   return extend;							  \
1264*e4b17023SJohn Marino }									  \
1265*e4b17023SJohn Marino 									  \
1266*e4b17023SJohn Marino static inline int VEC_OP (T,A,reserve_exact)   	    			  \
1267*e4b17023SJohn Marino      (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1268*e4b17023SJohn Marino {									  \
1269*e4b17023SJohn Marino   int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1270*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1271*e4b17023SJohn Marino 									  \
1272*e4b17023SJohn Marino   if (extend)								  \
1273*e4b17023SJohn Marino     *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact			  \
1274*e4b17023SJohn Marino 			 (*vec_, alloc_, offsetof (VEC(T,A),base.vec),	  \
1275*e4b17023SJohn Marino 			  sizeof (T) PASS_MEM_STAT);			  \
1276*e4b17023SJohn Marino 									  \
1277*e4b17023SJohn Marino   return extend;							  \
1278*e4b17023SJohn Marino }									  \
1279*e4b17023SJohn Marino 									  \
1280*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow)				  \
1281*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1282*e4b17023SJohn Marino {									  \
1283*e4b17023SJohn Marino   VEC_ASSERT (size_ >= 0						  \
1284*e4b17023SJohn Marino 	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
1285*e4b17023SJohn Marino 						 "grow", T, A);		  \
1286*e4b17023SJohn Marino   VEC_OP (T,A,reserve_exact) (vec_,					  \
1287*e4b17023SJohn Marino 			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \
1288*e4b17023SJohn Marino 			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
1289*e4b17023SJohn Marino   VEC_BASE (*vec_)->prefix.num = size_;					  \
1290*e4b17023SJohn Marino }									  \
1291*e4b17023SJohn Marino 									  \
1292*e4b17023SJohn Marino static inline void VEC_OP (T,A,safe_grow_cleared)			  \
1293*e4b17023SJohn Marino      (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
1294*e4b17023SJohn Marino {									  \
1295*e4b17023SJohn Marino   int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
1296*e4b17023SJohn Marino   VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
1297*e4b17023SJohn Marino   memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
1298*e4b17023SJohn Marino 	  sizeof (T) * (size_ - oldsize));				  \
1299*e4b17023SJohn Marino }									  \
1300*e4b17023SJohn Marino 									  \
1301*e4b17023SJohn Marino static inline void VEC_OP(T,A,safe_splice)				  \
1302*e4b17023SJohn Marino      (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
1303*e4b17023SJohn Marino {									  \
1304*e4b17023SJohn Marino   if (src_)								  \
1305*e4b17023SJohn Marino     {									  \
1306*e4b17023SJohn Marino       VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num			  \
1307*e4b17023SJohn Marino 				  VEC_CHECK_PASS MEM_STAT_INFO);	  \
1308*e4b17023SJohn Marino 									  \
1309*e4b17023SJohn Marino       VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_			  \
1310*e4b17023SJohn Marino 			      VEC_CHECK_PASS);				  \
1311*e4b17023SJohn Marino     }									  \
1312*e4b17023SJohn Marino }									  \
1313*e4b17023SJohn Marino 									  \
1314*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_push)					  \
1315*e4b17023SJohn Marino      (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
1316*e4b17023SJohn Marino {									  \
1317*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
1318*e4b17023SJohn Marino 									  \
1319*e4b17023SJohn Marino   return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
1320*e4b17023SJohn Marino }									  \
1321*e4b17023SJohn Marino 									  \
1322*e4b17023SJohn Marino static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
1323*e4b17023SJohn Marino      (VEC(T,A) **vec_, unsigned ix_, const T obj_			  \
1324*e4b17023SJohn Marino  		VEC_CHECK_DECL MEM_STAT_DECL)				  \
1325*e4b17023SJohn Marino {									  \
1326*e4b17023SJohn Marino   VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
1327*e4b17023SJohn Marino 									  \
1328*e4b17023SJohn Marino   return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
1329*e4b17023SJohn Marino 				       VEC_CHECK_PASS);			  \
1330*e4b17023SJohn Marino }
1331*e4b17023SJohn Marino 
1332*e4b17023SJohn Marino /* We support a vector which starts out with space on the stack and
1333*e4b17023SJohn Marino    switches to heap space when forced to reallocate.  This works a
1334*e4b17023SJohn Marino    little differently.  Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use
1335*e4b17023SJohn Marino    DEF_VEC_ALLOC_P_STACK(TYPE).  This uses alloca to get the initial
1336*e4b17023SJohn Marino    space; because alloca can not be usefully called in an inline
1337*e4b17023SJohn Marino    function, and because a macro can not define a macro, you must then
1338*e4b17023SJohn Marino    write a #define for each type:
1339*e4b17023SJohn Marino 
1340*e4b17023SJohn Marino    #define VEC_{TYPE}_stack_alloc(alloc)                          \
1341*e4b17023SJohn Marino      VEC_stack_alloc({TYPE}, alloc)
1342*e4b17023SJohn Marino 
1343*e4b17023SJohn Marino    This is really a hack and perhaps can be made better.  Note that
1344*e4b17023SJohn Marino    this macro will wind up evaluating the ALLOC parameter twice.
1345*e4b17023SJohn Marino 
1346*e4b17023SJohn Marino    Only the initial allocation will be made using alloca, so pass a
1347*e4b17023SJohn Marino    reasonable estimate that doesn't use too much stack space; don't
1348*e4b17023SJohn Marino    pass zero.  Don't return a VEC(TYPE,stack) vector from the function
1349*e4b17023SJohn Marino    which allocated it.  */
1350*e4b17023SJohn Marino 
1351*e4b17023SJohn Marino extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL);
1352*e4b17023SJohn Marino extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL);
1353*e4b17023SJohn Marino extern void *vec_stack_p_reserve_exact_1 (int, void *);
1354*e4b17023SJohn Marino extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
1355*e4b17023SJohn Marino extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
1356*e4b17023SJohn Marino 					 MEM_STAT_DECL);
1357*e4b17023SJohn Marino extern void vec_stack_free (void *);
1358*e4b17023SJohn Marino 
1359*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
1360*e4b17023SJohn Marino #define VEC_stack_alloc(T,alloc,name,line,function)			  \
1361*e4b17023SJohn Marino   (VEC_OP (T,stack,alloc1)						  \
1362*e4b17023SJohn Marino    (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
1363*e4b17023SJohn Marino #else
1364*e4b17023SJohn Marino #define VEC_stack_alloc(T,alloc)					  \
1365*e4b17023SJohn Marino   (VEC_OP (T,stack,alloc1)						  \
1366*e4b17023SJohn Marino    (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
1367*e4b17023SJohn Marino #endif
1368*e4b17023SJohn Marino 
1369*e4b17023SJohn Marino #define DEF_VEC_ALLOC_P_STACK(T)					  \
1370*e4b17023SJohn Marino VEC_TA(T,base,stack);							  \
1371*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_P_STACK(T)						  \
1372*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_P(T,stack)					  \
1373*e4b17023SJohn Marino struct vec_swallow_trailing_semi
1374*e4b17023SJohn Marino 
1375*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_P_STACK(T)					  \
1376*e4b17023SJohn Marino static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1377*e4b17023SJohn Marino      (int alloc_, VEC(T,stack)* space)					  \
1378*e4b17023SJohn Marino {									  \
1379*e4b17023SJohn Marino   return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);	  \
1380*e4b17023SJohn Marino }
1381*e4b17023SJohn Marino 
1382*e4b17023SJohn Marino #define DEF_VEC_ALLOC_O_STACK(T)					  \
1383*e4b17023SJohn Marino VEC_TA(T,base,stack);							  \
1384*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_O_STACK(T)						  \
1385*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_O(T,stack)					  \
1386*e4b17023SJohn Marino struct vec_swallow_trailing_semi
1387*e4b17023SJohn Marino 
1388*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_O_STACK(T)					  \
1389*e4b17023SJohn Marino static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1390*e4b17023SJohn Marino      (int alloc_, VEC(T,stack)* space)					  \
1391*e4b17023SJohn Marino {									  \
1392*e4b17023SJohn Marino   return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);	  \
1393*e4b17023SJohn Marino }
1394*e4b17023SJohn Marino 
1395*e4b17023SJohn Marino #define DEF_VEC_ALLOC_I_STACK(T)					  \
1396*e4b17023SJohn Marino VEC_TA(T,base,stack);							  \
1397*e4b17023SJohn Marino DEF_VEC_ALLOC_FUNC_I_STACK(T)						  \
1398*e4b17023SJohn Marino DEF_VEC_NONALLOC_FUNCS_I(T,stack)					  \
1399*e4b17023SJohn Marino struct vec_swallow_trailing_semi
1400*e4b17023SJohn Marino 
1401*e4b17023SJohn Marino #define DEF_VEC_ALLOC_FUNC_I_STACK(T)					  \
1402*e4b17023SJohn Marino static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1403*e4b17023SJohn Marino      (int alloc_, VEC(T,stack)* space)					  \
1404*e4b17023SJohn Marino {									  \
1405*e4b17023SJohn Marino   return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);   \
1406*e4b17023SJohn Marino }
1407*e4b17023SJohn Marino 
1408*e4b17023SJohn Marino #endif /* GCC_VEC_H */
1409