vec.h 45.8 KB
Newer Older
1
/* Vector API for GNU compiler.
2 3
   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.
4 5 6 7 8 9
   Contributed by Nathan Sidwell <nathan@codesourcery.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11 12 13 14 15 16 17 18
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
19 20
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
21 22 23 24 25 26 27 28 29 30 31

#ifndef GCC_VEC_H
#define GCC_VEC_H

/* The macros here implement a set of templated vector types and
   associated interfaces.  These templates are implemented with
   macros, as we're not in C++ land.  The interface functions are
   typesafe and use static inline functions, sometimes backed by
   out-of-line generic functions.  The vectors are designed to
   interoperate with the GTY machinery.

32 33 34 35 36 37 38 39
   Because of the different behavior of structure objects, scalar
   objects and of pointers, there are three flavors, one for each of
   these variants.  Both the structure object and pointer variants
   pass pointers to objects around -- in the former case the pointers
   are stored into the vector and in the latter case the pointers are
   dereferenced and the objects copied into the vector.  The scalar
   object variant is suitable for int-like objects, and the vector
   elements are returned by value.
40

41 42 43 44 45
   There are both 'index' and 'iterate' accessors.  The iterator
   returns a boolean iteration condition and updates the iteration
   variable passed by reference.  Because the iterator will be
   inlined, the address-of can be optimized away.

46 47 48 49 50
   The vectors are implemented using the trailing array idiom, thus
   they are not resizeable without changing the address of the vector
   object itself.  This means you cannot have variables or fields of
   vector type -- always use a pointer to a vector.  The one exception
   is the final field of a structure, which could be a vector type.
51 52 53 54 55 56
   You will have to use the embedded_size & embedded_init calls to
   create such objects, and they will probably not be resizeable (so
   don't use the 'safe' allocation variants).  The trailing array
   idiom is used (rather than a pointer to an array of data), because,
   if we allow NULL to also represent an empty vector, empty vectors
   occupy minimal space in the structure containing them.
57 58 59 60

   Each operation that increases the number of active elements is
   available in 'quick' and 'safe' variants.  The former presumes that
   there is sufficient allocated space for the operation to succeed
61
   (it dies if there is not).  The latter will reallocate the
62 63 64
   vector, if needed.  Reallocation causes an exponential increase in
   vector size.  If you know you will be adding N elements, it would
   be more efficient to use the reserve operation before adding the
65 66 67 68
   elements with the 'quick' operation.  This will ensure there are at
   least as many elements as you ask for, it will exponentially
   increase if there are too few spare slots.  If you want reserve a
   specific number of slots, but do not want the exponential increase
69 70
   (for instance, you know this is the last allocation), use the
   reserve_exact operation.  You can also create a vector of a
71
   specific size from the get go.
72 73

   You should prefer the push and pop operations, as they append and
74 75
   remove from the end of the vector. If you need to remove several
   items in one go, use the truncate operation.  The insert and remove
76 77 78 79
   operations allow you to change elements in the middle of the
   vector.  There are two remove operations, one which preserves the
   element ordering 'ordered_remove', and one which does not
   'unordered_remove'.  The latter function copies the end element
80 81
   into the removed slot, rather than invoke a memmove operation.  The
   'lower_bound' function will determine where to place an item in the
82
   array using insert that will maintain sorted order.
83

84 85 86 87 88 89
   When a vector type is defined, first a non-memory managed version
   is created.  You can then define either or both garbage collected
   and heap allocated versions.  The allocation mechanism is specified
   when the type is defined, and is therefore part of the type.  If
   you need both gc'd and heap allocated versions, you still must have
   *exactly* one definition of the common non-memory managed base vector.
H.J. Lu committed
90

91 92 93 94
   If you need to directly manipulate a vector, then the 'address'
   accessor will return the address of the start of the vector.  Also
   the 'space' predicate will tell you whether there is spare capacity
   in the vector.  You will not normally need to use these two functions.
H.J. Lu committed
95

96
   Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
97
   get the non-memory allocation version, and then a
98
   DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
99 100 101 102 103
   vectors.  Variables of vector type are declared using a
   VEC(TYPEDEF,ALLOC) macro.  The ALLOC argument specifies the
   allocation strategy, and can be either 'gc' or 'heap' for garbage
   collected and heap allocated respectively.  It can be 'none' to get
   a vector that must be explicitly allocated (for instance as a
104 105 106 107 108 109 110 111 112 113
   trailing array of another structure).  The characters O, P and I
   indicate whether TYPEDEF is a pointer (P), object (O) or integral
   (I) type.  Be careful to pick the correct one, as you'll get an
   awkward and inefficient API if you use the wrong one.  There is a
   check, which results in a compile-time warning, for the P and I
   versions, but there is no check for the O versions, as that is not
   possible in plain C.  Due to the way GTY works, you must annotate
   any structures you wish to insert or reference from a vector with a
   GTY(()) tag.  You need to do this even if you never declare the GC
   allocated variants.
114 115 116

   An example of their use would be,

117 118 119
   DEF_VEC_P(tree);   // non-managed tree vector.
   DEF_VEC_ALLOC_P(tree,gc);	// gc'd vector of tree pointers.  This must
   			        // appear at file scope.
120 121

   struct my_struct {
122
     VEC(tree,gc) *v;      // A (pointer to) a vector of tree pointers.
123 124 125 126
   };

   struct my_struct *s;

127
   if (VEC_length(tree,s->v)) { we have some contents }
128
   VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
129 130
   for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
     { do something with elt }
131 132 133 134 135

*/

/* Macros to invoke API calls.  A single macro works for both pointer
   and object vectors, but the argument and return types might well be
136 137 138 139 140
   different.  In each macro, T is the typedef of the vector elements,
   and A is the allocation strategy.  The allocation strategy is only
   present when it is required.  Some of these macros pass the vector,
   V, by reference (by taking its address), this is noted in the
   descriptions.  */
141 142

/* Length of vector
143
   unsigned VEC_T_length(const VEC(T) *v);
144 145 146

   Return the number of active elements in V.  V can be NULL, in which
   case zero is returned.  */
147

148
#define VEC_length(T,V)	(VEC_OP(T,base,length)(VEC_BASE(V)))
149

150 151 152 153

/* Check if vector is empty
   int VEC_T_empty(const VEC(T) *v);

154
   Return nonzero if V is an empty vector (or V is NULL), zero otherwise.  */
155 156 157 158

#define VEC_empty(T,V)	(VEC_length (T,V) == 0)


159
/* Get the final element of the vector.
160
   T VEC_T_last(VEC(T) *v); // Integer
161 162 163
   T VEC_T_last(VEC(T) *v); // Pointer
   T *VEC_T_last(VEC(T) *v); // Object

164
   Return the final element.  V must not be empty.  */
165

166
#define VEC_last(T,V)	(VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
167 168

/* Index into vector
169
   T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
170 171
   T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
   T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
172

173
   Return the IX'th element.  If IX must be in the domain of V.  */
174

175
#define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
176 177

/* Iterate over vector
178
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
179 180
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
181

182 183 184
   Return iteration condition and update PTR to point to the IX'th
   element.  At the end of iteration, sets PTR to NULL.  Use this to
   iterate over the elements of a vector as follows,
185

186
     for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
187
       continue;  */
188

189
#define VEC_iterate(T,V,I,P)	(VEC_OP(T,base,iterate)(VEC_BASE(V),I,&(P)))
190 191

/* Allocate new vector.
192
   VEC(T,A) *VEC_T_A_alloc(int reserve);
193

194
   Allocate a new vector with space for RESERVE objects.  If RESERVE
195
   is zero, NO vector is created.  */
196

197
#define VEC_alloc(T,A,N)	(VEC_OP(T,A,alloc)(N MEM_STAT_INFO))
198

199
/* Free a vector.
200
   void VEC_T_A_free(VEC(T,A) *&);
201 202 203

   Free a vector and set it to NULL.  */

204
#define VEC_free(T,A,V)	(VEC_OP(T,A,free)(&V))
205

206 207
/* Use these to determine the required size and initialization of a
   vector embedded within another structure (as the final member).
H.J. Lu committed
208

209 210
   size_t VEC_T_embedded_size(int reserve);
   void VEC_T_embedded_init(VEC(T) *v, int reserve);
H.J. Lu committed
211

212
   These allow the caller to perform the memory allocation.  */
213

214 215
#define VEC_embedded_size(T,N)	 (VEC_OP(T,base,embedded_size)(N))
#define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N))
216

217 218 219 220
/* Copy a vector.
   VEC(T,A) *VEC_T_A_copy(VEC(T) *);

   Copy the live elements of a vector into a new vector.  The new and
221
   old vectors need not be allocated by the same mechanism.  */
222 223 224

#define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO))

225
/* Determine if a vector has additional capacity.
H.J. Lu committed
226

227 228
   int VEC_T_space (VEC(T) *v,int reserve)

229
   If V has space for RESERVE additional entries, return nonzero.  You
230 231
   usually only need to use this if you are doing your own vector
   reallocation, for instance on an embedded vector.  This returns
232
   nonzero in exactly the same circumstances that VEC_T_reserve
233 234
   will.  */

235 236
#define VEC_space(T,V,R) \
	(VEC_OP(T,base,space)(VEC_BASE(V),R VEC_CHECK_INFO))
237 238

/* Reserve space.
239
   int VEC_T_A_reserve(VEC(T,A) *&v, int reserve);
240

241 242 243 244
   Ensure that V has at least RESERVE slots available.  This will
   create additional headroom.  Note this can cause V to be
   reallocated.  Returns nonzero iff reallocation actually
   occurred.  */
245

246 247
#define VEC_reserve(T,A,V,R)	\
	(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
248

249 250 251 252 253 254 255 256 257 258 259
/* Reserve space exactly.
   int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve);

   Ensure that V has at least RESERVE slots available.  This will not
   create additional headroom.  Note this can cause V to be
   reallocated.  Returns nonzero iff reallocation actually
   occurred.  */

#define VEC_reserve_exact(T,A,V,R)	\
	(VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))

260
/* Push object with no reallocation
261
   T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
262 263
   T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
   T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
H.J. Lu committed
264

265 266
   Push a new element onto the end, returns a pointer to the slot
   filled in. For object vectors, the new value can be NULL, in which
267 268
   case NO initialization is performed.  There must
   be sufficient space in the vector.  */
269

270 271
#define VEC_quick_push(T,V,O)	\
	(VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
272 273

/* Push object with reallocation
274
   T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
275 276
   T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
   T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
H.J. Lu committed
277

278 279 280
   Push a new element onto the end, returns a pointer to the slot
   filled in. For object vectors, the new value can be NULL, in which
   case NO initialization is performed.  Reallocates V, if needed.  */
281

282 283
#define VEC_safe_push(T,A,V,O)		\
	(VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
284 285

/* Pop element off end
286
   T VEC_T_pop (VEC(T) *v);		// Integer
287 288 289 290 291
   T VEC_T_pop (VEC(T) *v);		// Pointer
   void VEC_T_pop (VEC(T) *v);		// Object

   Pop the last element off the end. Returns the element popped, for
   pointer vectors.  */
292

293
#define VEC_pop(T,V)	(VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO))
294

295
/* Truncate to specific length
296
   void VEC_T_truncate (VEC(T) *v, unsigned len);
H.J. Lu committed
297

298 299
   Set the length as specified.  The new length must be less than or
   equal to the current length.  This is an O(1) operation.  */
300

301 302 303 304 305 306 307 308 309 310 311
#define VEC_truncate(T,V,I)		\
	(VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO))

/* Grow to a specific length.
   void VEC_T_A_safe_grow (VEC(T,A) *&v, int len);

   Grow the vector to a specific length.  The LEN must be as
   long or longer than the current length.  The new elements are
   uninitialized.  */

#define VEC_safe_grow(T,A,V,I)		\
312
	(VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))
313

314 315 316 317 318 319 320 321 322 323
/* Grow to a specific length.
   void VEC_T_A_safe_grow_cleared (VEC(T,A) *&v, int len);

   Grow the vector to a specific length.  The LEN must be as
   long or longer than the current length.  The new elements are
   initialized to zero.  */

#define VEC_safe_grow_cleared(T,A,V,I)		\
	(VEC_OP(T,A,safe_grow_cleared)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))

324
/* Replace element
325
   T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
326 327
   T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
   T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val);  // Object
H.J. Lu committed
328

329 330 331 332 333
   Replace the IXth element of V with a new value, VAL.  For pointer
   vectors returns the original value. For object vectors returns a
   pointer to the new value.  For object vectors the new value can be
   NULL, in which case no overwriting of the slot is actually
   performed.  */
334

335 336
#define VEC_replace(T,V,I,O)		\
	(VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
337 338

/* Insert object with no reallocation
339
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
340 341
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
H.J. Lu committed
342

343 344 345
   Insert an element, VAL, at the IXth position of V. Return a pointer
   to the slot created.  For vectors of object, the new value can be
   NULL, in which case no initialization of the inserted slot takes
346
   place. There must be sufficient space.  */
347

348 349
#define VEC_quick_insert(T,V,I,O)	\
	(VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
350 351

/* Insert object with reallocation
352
   T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
353 354
   T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
   T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
H.J. Lu committed
355

356 357 358 359
   Insert an element, VAL, at the IXth position of V. Return a pointer
   to the slot created.  For vectors of object, the new value can be
   NULL, in which case no initialization of the inserted slot takes
   place. Reallocate V, if necessary.  */
360

361 362
#define VEC_safe_insert(T,A,V,I,O)	\
	(VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
H.J. Lu committed
363

364
/* Remove element retaining order
365
   T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
366 367
   T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
   void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
H.J. Lu committed
368

369
   Remove an element from the IXth position of V. Ordering of
370
   remaining elements is preserved.  For pointer vectors returns the
371
   removed object.  This is an O(N) operation due to a memmove.  */
372

373 374
#define VEC_ordered_remove(T,V,I)	\
	(VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
375 376

/* Remove element destroying order
377
   T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
378 379
   T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
   void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
H.J. Lu committed
380

381 382 383
   Remove an element from the IXth position of V. Ordering of
   remaining elements is destroyed.  For pointer vectors returns the
   removed object.  This is an O(1) operation.  */
384

385 386
#define VEC_unordered_remove(T,V,I)	\
	(VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
387

388 389
/* Remove a block of elements
   void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
H.J. Lu committed
390

391 392 393 394 395 396
   Remove LEN elements starting at the IXth.  Ordering is retained.
   This is an O(1) operation.  */

#define VEC_block_remove(T,V,I,L)	\
	(VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO))

397 398 399 400 401
/* Get the address of the array of elements
   T *VEC_T_address (VEC(T) v)

   If you need to directly manipulate the array (for instance, you
   want to feed it to qsort), use this accessor.  */
402

403
#define VEC_address(T,V)		(VEC_OP(T,base,address)(VEC_BASE(V)))
404

405
/* Find the first index in the vector not less than the object.
H.J. Lu committed
406
   unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
407
                               bool (*lessthan) (const T, const T)); // Integer
H.J. Lu committed
408
   unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
409 410 411
                               bool (*lessthan) (const T, const T)); // Pointer
   unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
                               bool (*lessthan) (const T*, const T*)); // Object
H.J. Lu committed
412

413 414
   Find the first position in which VAL could be inserted without
   changing the ordering of V.  LESSTHAN is a function that returns
415
   true if the first argument is strictly less than the second.  */
H.J. Lu committed
416

417 418
#define VEC_lower_bound(T,V,O,LT)    \
       (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO))
419

420
/* Reallocate an array of elements with prefix.  */
421
extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
422
extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
423
extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
424 425
extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
				     MEM_STAT_DECL);
426 427
extern void ggc_free (void *);
#define vec_gc_free(V) ggc_free (V)
428
extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
429
extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
430
extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
431 432
extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
				       MEM_STAT_DECL);
433 434 435 436
extern void dump_vec_loc_statistics (void);
#ifdef GATHER_STATISTICS
void vec_heap_free (void *);
#else
437
#define vec_heap_free(V) free (V)
438
#endif
439 440

#if ENABLE_CHECKING
441 442 443
#define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
#define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_
#define VEC_CHECK_PASS ,file_,line_,function_
H.J. Lu committed
444

445 446
#define VEC_ASSERT(EXPR,OP,T,A) \
  (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
447 448 449 450

extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
     ATTRIBUTE_NORETURN;
#define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
451
#else
452 453 454
#define VEC_CHECK_INFO
#define VEC_CHECK_DECL
#define VEC_CHECK_PASS
455
#define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
456 457
#endif

458 459 460 461
/* Note: gengtype has hardwired knowledge of the expansions of the
   VEC, DEF_VEC_*, and DEF_VEC_ALLOC_* macros.  If you change the
   expansions of these macros you may need to change gengtype too.  */

462 463
#define VEC(T,A) VEC_##T##_##A
#define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP
464

H.J. Lu committed
465
/* Base of vector type, not user visible.  */
466
#define VEC_T(T,B)							  \
467 468 469 470 471 472 473 474
typedef struct VEC(T,B) 				 		  \
{									  \
  unsigned num;								  \
  unsigned alloc;							  \
  T vec[1];								  \
} VEC(T,B)

#define VEC_T_GTY(T,B)							  \
475
typedef struct GTY(()) VEC(T,B)				 		  \
476
{									  \
477 478
  unsigned num;								  \
  unsigned alloc;							  \
479 480 481 482
  T GTY ((length ("%h.num"))) vec[1];					  \
} VEC(T,B)

/* Derived vector type, user visible.  */
483
#define VEC_TA_GTY(T,B,A,GTY)						  \
484
typedef struct GTY VEC(T,A)						  \
485 486 487 488
{									  \
  VEC(T,B) base;							  \
} VEC(T,A)

489 490 491 492 493 494
#define VEC_TA(T,B,A)							  \
typedef struct VEC(T,A)							  \
{									  \
  VEC(T,B) base;							  \
} VEC(T,A)

495 496
/* Convert to base type.  */
#define VEC_BASE(P)  ((P) ? &(P)->base : 0)
497

498 499 500 501 502 503 504 505
/* Vector of integer-like object.  */
#define DEF_VEC_I(T)							  \
static inline void VEC_OP (T,must_be,integral_type) (void) 		  \
{									  \
  (void)~(T)0;								  \
}									  \
									  \
VEC_T(T,base);								  \
506
VEC_TA(T,base,none);							  \
507 508 509
DEF_VEC_FUNC_P(T)							  \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I(T,A)						  \
510
VEC_TA(T,base,A);							  \
511
DEF_VEC_ALLOC_FUNC_I(T,A)						  \
512
DEF_VEC_NONALLOC_FUNCS_I(T,A)						  \
513 514
struct vec_swallow_trailing_semi

515
/* Vector of pointer to object.  */
516
#define DEF_VEC_P(T) 							  \
517
static inline void VEC_OP (T,must_be,pointer_type) (void) 		  \
518
{									  \
519
  (void)((T)1 == (void *)1);						  \
520 521
}									  \
									  \
522
VEC_T_GTY(T,base);							  \
523
VEC_TA(T,base,none);							  \
524 525 526
DEF_VEC_FUNC_P(T)							  \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_P(T,A)						  \
527
VEC_TA(T,base,A);							  \
528
DEF_VEC_ALLOC_FUNC_P(T,A)						  \
529
DEF_VEC_NONALLOC_FUNCS_P(T,A)						  \
530 531 532
struct vec_swallow_trailing_semi

#define DEF_VEC_FUNC_P(T)						  \
533
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)   \
534 535 536 537
{									  \
  return vec_ ? vec_->num : 0;						  \
}									  \
									  \
538 539
static inline T VEC_OP (T,base,last)					  \
     (const VEC(T,base) *vec_ VEC_CHECK_DECL)				  \
540
{									  \
541
  VEC_ASSERT (vec_ && vec_->num, "last", T, base);			  \
542
  									  \
Nathan Sidwell committed
543
  return vec_->vec[vec_->num - 1];					  \
544 545
}									  \
									  \
546 547
static inline T VEC_OP (T,base,index)					  \
     (const VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)		  \
548
{									  \
549
  VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base);		  \
550 551 552 553
  									  \
  return vec_->vec[ix_];						  \
}									  \
									  \
554 555
static inline int VEC_OP (T,base,iterate)			  	  \
     (const VEC(T,base) *vec_, unsigned ix_, T *ptr)			  \
556
{									  \
557 558 559 560 561 562 563
  if (vec_ && ix_ < vec_->num)						  \
    {									  \
      *ptr = vec_->vec[ix_];						  \
      return 1;								  \
    }									  \
  else									  \
    {									  \
564
      *ptr = (T) 0;							  \
565 566
      return 0;								  \
    }									  \
567 568
}									  \
									  \
569
static inline size_t VEC_OP (T,base,embedded_size)			  \
570
     (int alloc_)							  \
571
{									  \
572
  return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);		  \
573 574
}									  \
									  \
575 576
static inline void VEC_OP (T,base,embedded_init)			  \
     (VEC(T,base) *vec_, int alloc_)					  \
577 578 579
{									  \
  vec_->num = 0;							  \
  vec_->alloc = alloc_;							  \
580 581
}									  \
									  \
582 583
static inline int VEC_OP (T,base,space)	       				  \
     (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)			  \
584
{									  \
585 586
  VEC_ASSERT (alloc_ >= 0, "space", T, base);				  \
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;	  \
587 588
}									  \
									  \
589 590
static inline T *VEC_OP (T,base,quick_push)				  \
     (VEC(T,base) *vec_, T obj_ VEC_CHECK_DECL)				  \
591
{									  \
592
  T *slot_;								  \
593
  									  \
594
  VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base);		  \
595 596 597 598 599 600
  slot_ = &vec_->vec[vec_->num++];					  \
  *slot_ = obj_;							  \
  									  \
  return slot_;								  \
}									  \
									  \
601
static inline T VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL)	  \
602
{									  \
603
  T obj_;								  \
604
									  \
605
  VEC_ASSERT (vec_->num, "pop", T, base);				  \
606 607 608 609 610
  obj_ = vec_->vec[--vec_->num];					  \
									  \
  return obj_;								  \
}									  \
									  \
611 612
static inline void VEC_OP (T,base,truncate)				  \
     (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)			  \
613
{									  \
614
  VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base);	  \
615 616
  if (vec_)								  \
    vec_->num = size_;							  \
617 618
}									  \
									  \
619 620
static inline T VEC_OP (T,base,replace)		  	     		  \
     (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)		  \
621
{									  \
622
  T old_obj_;								  \
623
									  \
624
  VEC_ASSERT (ix_ < vec_->num, "replace", T, base);			  \
625 626 627 628 629 630
  old_obj_ = vec_->vec[ix_];						  \
  vec_->vec[ix_] = obj_;						  \
									  \
  return old_obj_;							  \
}									  \
									  \
631 632 633 634 635 636 637
static inline T *VEC_OP (T,base,quick_insert)				  \
     (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)		  \
{									  \
  T *slot_;								  \
									  \
  VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base);		  \
  VEC_ASSERT (ix_ <= vec_->num, "insert", T, base);			  \
638
  slot_ = &vec_->vec[ix_];						  \
639
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));		  \
640 641 642 643 644
  *slot_ = obj_;							  \
  									  \
  return slot_;								  \
}									  \
									  \
645 646
static inline T VEC_OP (T,base,ordered_remove)				  \
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
647
{									  \
648 649
  T *slot_;								  \
  T obj_;								  \
650
									  \
651
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);			  \
652 653
  slot_ = &vec_->vec[ix_];						  \
  obj_ = *slot_;							  \
654
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));     	  \
655 656 657 658
									  \
  return obj_;								  \
}									  \
									  \
659 660
static inline T VEC_OP (T,base,unordered_remove)			  \
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
661
{									  \
662 663
  T *slot_;								  \
  T obj_;								  \
664
									  \
665
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);			  \
666 667 668 669 670 671 672
  slot_ = &vec_->vec[ix_];						  \
  obj_ = *slot_;							  \
  *slot_ = vec_->vec[--vec_->num];					  \
									  \
  return obj_;								  \
}									  \
									  \
673 674 675 676 677 678 679 680 681 682 683
static inline void VEC_OP (T,base,block_remove)				  \
     (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)	  \
{									  \
  T *slot_;								  \
									  \
  VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base);	  \
  slot_ = &vec_->vec[ix_];						  \
  vec_->num -= len_;							  \
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));	  \
}									  \
									  \
684 685
static inline T *VEC_OP (T,base,address)				  \
     (VEC(T,base) *vec_)						  \
686 687 688 689
{									  \
  return vec_ ? vec_->vec : 0;						  \
}									  \
									  \
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
static inline unsigned VEC_OP (T,base,lower_bound)			  \
     (VEC(T,base) *vec_, const T obj_,					  \
      bool (*lessthan_)(const T, const T) VEC_CHECK_DECL)		  \
{									  \
   unsigned int len_ = VEC_OP (T,base, length) (vec_);			  \
   unsigned int half_, middle_;						  \
   unsigned int first_ = 0;						  \
   while (len_ > 0)							  \
     {									  \
        T middle_elem_;							  \
        half_ = len_ >> 1;						  \
        middle_ = first_;						  \
        middle_ += half_;						  \
        middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
        if (lessthan_ (middle_elem_, obj_))				  \
          {								  \
             first_ = middle_;						  \
             ++first_;							  \
             len_ = len_ - half_ - 1;					  \
          }								  \
        else								  \
          len_ = half_;							  \
     }									  \
   return first_;							  \
714 715 716
}

#define DEF_VEC_ALLOC_FUNC_P(T,A)					  \
717 718 719
static inline VEC(T,A) *VEC_OP (T,A,alloc)				  \
     (int alloc_ MEM_STAT_DECL)						  \
{									  \
720 721
  return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_		  \
						 PASS_MEM_STAT);	  \
722 723 724 725
}


#define DEF_VEC_NONALLOC_FUNCS_P(T,A)					  \
726 727 728 729 730 731 732 733
static inline void VEC_OP (T,A,free)					  \
     (VEC(T,A) **vec_)							  \
{									  \
  if (*vec_)								  \
    vec_##A##_free (*vec_);						  \
  *vec_ = NULL;								  \
}									  \
									  \
734 735 736 737 738 739 740
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
{									  \
  size_t len_ = vec_ ? vec_->num : 0;					  \
  VEC (T,A) *new_vec_ = NULL;						  \
									  \
  if (len_)								  \
    {									  \
741 742
      new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact		  \
			       (NULL, len_ PASS_MEM_STAT));		  \
743 744 745 746 747 748 749
									  \
      new_vec_->base.num = len_;					  \
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
    }									  \
  return new_vec_;							  \
}									  \
									  \
750 751 752
static inline int VEC_OP (T,A,reserve)	       				  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
753
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
754 755 756 757 758 759 760 761
				       VEC_CHECK_PASS);			  \
		  							  \
  if (extend)	  							  \
    *vec_ = (VEC(T,A) *) vec_##A##_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \
		  							  \
  return extend;							  \
}									  \
									  \
762 763 764 765 766 767 768 769 770 771 772 773 774
static inline int VEC_OP (T,A,reserve_exact)  				  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
				       VEC_CHECK_PASS);			  \
		  							  \
  if (extend)	  							  \
    *vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_	  \
						    PASS_MEM_STAT);	  \
		  							  \
  return extend;							  \
}									  \
									  \
775 776 777 778 779 780
static inline void VEC_OP (T,A,safe_grow)				  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  VEC_ASSERT (size_ >= 0						  \
	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
						 "grow", T, A);		  \
781 782 783
  VEC_OP (T,A,reserve_exact) (vec_,					  \
			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
784 785 786
  VEC_BASE (*vec_)->num = size_;					  \
}									  \
									  \
787 788 789 790 791 792 793 794 795
static inline void VEC_OP (T,A,safe_grow_cleared)			  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
  VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
  memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
	  sizeof (T) * (size_ - oldsize));				  \
}									  \
									  \
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
static inline T *VEC_OP (T,A,safe_push)					  \
     (VEC(T,A) **vec_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL)       	  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
}									  \
									  \
static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
     (VEC(T,A) **vec_, unsigned ix_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL)  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
 				       VEC_CHECK_PASS);			  \
811
}
812 813

/* Vector of object.  */
814
#define DEF_VEC_O(T)							  \
815
VEC_T_GTY(T,base);							  \
816
VEC_TA(T,base,none);						  \
817 818 819
DEF_VEC_FUNC_O(T)							  \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_O(T,A)						  \
820
VEC_TA(T,base,A);							  \
821
DEF_VEC_ALLOC_FUNC_O(T,A)						  \
822
DEF_VEC_NONALLOC_FUNCS_O(T,A)						  \
823 824 825
struct vec_swallow_trailing_semi

#define DEF_VEC_FUNC_O(T)						  \
826
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)	  \
827 828 829 830
{									  \
  return vec_ ? vec_->num : 0;						  \
}									  \
									  \
831
static inline T *VEC_OP (T,base,last) (VEC(T,base) *vec_ VEC_CHECK_DECL)  \
832
{									  \
833
  VEC_ASSERT (vec_ && vec_->num, "last", T, base);			  \
834 835 836 837
  									  \
  return &vec_->vec[vec_->num - 1];					  \
}									  \
									  \
838 839
static inline T *VEC_OP (T,base,index)					  \
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
840
{									  \
841
  VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base);		  \
842 843 844 845
  									  \
  return &vec_->vec[ix_];						  \
}									  \
									  \
846 847
static inline int VEC_OP (T,base,iterate)			     	  \
     (VEC(T,base) *vec_, unsigned ix_, T **ptr)				  \
848
{									  \
849 850 851 852 853 854 855 856 857 858
  if (vec_ && ix_ < vec_->num)						  \
    {									  \
      *ptr = &vec_->vec[ix_];						  \
      return 1;								  \
    }									  \
  else									  \
    {									  \
      *ptr = 0;								  \
      return 0;								  \
    }									  \
859 860
}									  \
									  \
861
static inline size_t VEC_OP (T,base,embedded_size)			  \
862
     (int alloc_)							  \
863
{									  \
864
  return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);		  \
865 866
}									  \
									  \
867 868
static inline void VEC_OP (T,base,embedded_init)			  \
     (VEC(T,base) *vec_, int alloc_)					  \
869
{									  \
870 871
  vec_->num = 0;							  \
  vec_->alloc = alloc_;							  \
872 873
}									  \
									  \
874 875
static inline int VEC_OP (T,base,space)	       				  \
     (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)			  \
876
{									  \
877 878
  VEC_ASSERT (alloc_ >= 0, "space", T, base);				  \
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;	  \
879 880
}									  \
									  \
881 882
static inline T *VEC_OP (T,base,quick_push)				  \
     (VEC(T,base) *vec_, const T *obj_ VEC_CHECK_DECL)			  \
883
{									  \
884
  T *slot_;								  \
885
  									  \
886
  VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base);		  \
887 888 889 890 891 892 893
  slot_ = &vec_->vec[vec_->num++];					  \
  if (obj_)								  \
    *slot_ = *obj_;							  \
  									  \
  return slot_;								  \
}									  \
									  \
894
static inline void VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
895
{									  \
896
  VEC_ASSERT (vec_->num, "pop", T, base);				  \
897 898 899
  --vec_->num;								  \
}									  \
									  \
900 901
static inline void VEC_OP (T,base,truncate)				  \
     (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)			  \
902
{									  \
903
  VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base);	  \
904 905
  if (vec_)								  \
    vec_->num = size_;							  \
906 907
}									  \
									  \
908 909
static inline T *VEC_OP (T,base,replace)				  \
     (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)	  \
910
{									  \
911
  T *slot_;								  \
912
									  \
913
  VEC_ASSERT (ix_ < vec_->num, "replace", T, base);			  \
914 915 916 917 918 919 920
  slot_ = &vec_->vec[ix_];						  \
  if (obj_)								  \
    *slot_ = *obj_;							  \
									  \
  return slot_;								  \
}									  \
									  \
921 922 923 924 925 926 927
static inline T *VEC_OP (T,base,quick_insert)				  \
     (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)	  \
{									  \
  T *slot_;								  \
									  \
  VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base);		  \
  VEC_ASSERT (ix_ <= vec_->num, "insert", T, base);			  \
928
  slot_ = &vec_->vec[ix_];						  \
929
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));		  \
930 931 932 933 934 935
  if (obj_)								  \
    *slot_ = *obj_;							  \
  									  \
  return slot_;								  \
}									  \
									  \
936 937
static inline void VEC_OP (T,base,ordered_remove)			  \
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
938
{									  \
939
  T *slot_;								  \
940
									  \
941 942 943
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);			  \
  slot_ = &vec_->vec[ix_];						  \
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));		  \
944 945
}									  \
									  \
946 947
static inline void VEC_OP (T,base,unordered_remove)			  \
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)			  \
948
{									  \
949 950 951
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);			  \
  vec_->vec[ix_] = vec_->vec[--vec_->num];				  \
}									  \
952
									  \
953 954 955 956 957 958 959 960 961 962 963
static inline void VEC_OP (T,base,block_remove)				  \
     (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)	  \
{									  \
  T *slot_;								  \
									  \
  VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base);	  \
  slot_ = &vec_->vec[ix_];						  \
  vec_->num -= len_;							  \
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));	  \
}									  \
									  \
964 965 966 967
static inline T *VEC_OP (T,base,address)				  \
     (VEC(T,base) *vec_)						  \
{									  \
  return vec_ ? vec_->vec : 0;						  \
968 969
}									  \
									  \
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
static inline unsigned VEC_OP (T,base,lower_bound)			  \
     (VEC(T,base) *vec_, const T *obj_,					  \
      bool (*lessthan_)(const T *, const T *) VEC_CHECK_DECL)		  \
{									  \
   unsigned int len_ = VEC_OP (T, base, length) (vec_);			  \
   unsigned int half_, middle_;						  \
   unsigned int first_ = 0;						  \
   while (len_ > 0)							  \
     {									  \
        T *middle_elem_;						  \
        half_ = len_ >> 1;						  \
        middle_ = first_;						  \
        middle_ += half_;						  \
        middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
        if (lessthan_ (middle_elem_, obj_))				  \
          {								  \
             first_ = middle_;						  \
             ++first_;							  \
             len_ = len_ - half_ - 1;					  \
          }								  \
        else								  \
          len_ = half_;							  \
     }									  \
   return first_;							  \
994
}
995

996
#define DEF_VEC_ALLOC_FUNC_O(T,A)					  \
997 998
static inline VEC(T,A) *VEC_OP (T,A,alloc)      			  \
     (int alloc_ MEM_STAT_DECL)						  \
999
{									  \
1000 1001 1002 1003
  return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_,		  \
						 offsetof (VEC(T,A),base.vec), \
						 sizeof (T)		  \
						 PASS_MEM_STAT);	  \
1004 1005 1006
}

#define DEF_VEC_NONALLOC_FUNCS_O(T,A)					  \
1007 1008 1009 1010 1011 1012 1013
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
{									  \
  size_t len_ = vec_ ? vec_->num : 0;					  \
  VEC (T,A) *new_vec_ = NULL;						  \
									  \
  if (len_)								  \
    {									  \
1014 1015
      new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact		  \
			       (NULL, len_,				  \
1016 1017 1018 1019 1020 1021 1022 1023 1024
				offsetof (VEC(T,A),base.vec), sizeof (T)  \
				PASS_MEM_STAT));			  \
									  \
      new_vec_->base.num = len_;					  \
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
    }									  \
  return new_vec_;							  \
}									  \
									  \
1025 1026
static inline void VEC_OP (T,A,free)					  \
     (VEC(T,A) **vec_)							  \
1027
{									  \
1028 1029 1030 1031 1032 1033 1034 1035
  if (*vec_)								  \
    vec_##A##_free (*vec_);						  \
  *vec_ = NULL;								  \
}									  \
									  \
static inline int VEC_OP (T,A,reserve)	   	    			  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
1036
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
				       VEC_CHECK_PASS);			  \
									  \
  if (extend)								  \
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,		  \
			   		      offsetof (VEC(T,A),base.vec),\
 					      sizeof (T)		  \
			   		      PASS_MEM_STAT);		  \
									  \
  return extend;							  \
}									  \
									  \
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
static inline int VEC_OP (T,A,reserve_exact)   	    			  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
				       VEC_CHECK_PASS);			  \
									  \
  if (extend)								  \
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact			  \
			 (*vec_, alloc_,				  \
			  offsetof (VEC(T,A),base.vec),			  \
			  sizeof (T) PASS_MEM_STAT);			  \
									  \
  return extend;							  \
}									  \
									  \
1063 1064 1065 1066 1067 1068
static inline void VEC_OP (T,A,safe_grow)				  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  VEC_ASSERT (size_ >= 0						  \
	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
						 "grow", T, A);		  \
1069 1070 1071
  VEC_OP (T,A,reserve_exact) (vec_,					  \
			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
1072 1073 1074
  VEC_BASE (*vec_)->num = size_;					  \
}									  \
									  \
1075 1076 1077 1078 1079 1080 1081 1082 1083
static inline void VEC_OP (T,A,safe_grow_cleared)			  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
  VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
  memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
	  sizeof (T) * (size_ - oldsize));				  \
}									  \
									  \
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
static inline T *VEC_OP (T,A,safe_push)					  \
     (VEC(T,A) **vec_, const T *obj_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
}									  \
									  \
static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
     (VEC(T,A) **vec_, unsigned ix_, const T *obj_			  \
 		VEC_CHECK_DECL MEM_STAT_DECL)				  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
				       VEC_CHECK_PASS);			  \
1100
}
1101 1102 1103 1104 1105

#define DEF_VEC_ALLOC_FUNC_I(T,A)					  \
static inline VEC(T,A) *VEC_OP (T,A,alloc)      			  \
     (int alloc_ MEM_STAT_DECL)						  \
{									  \
1106 1107 1108
  return (VEC(T,A) *) vec_##A##_o_reserve_exact				  \
		      (NULL, alloc_, offsetof (VEC(T,A),base.vec),	  \
		       sizeof (T) PASS_MEM_STAT);			  \
1109 1110 1111
}

#define DEF_VEC_NONALLOC_FUNCS_I(T,A)					  \
1112 1113 1114 1115 1116 1117 1118
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
{									  \
  size_t len_ = vec_ ? vec_->num : 0;					  \
  VEC (T,A) *new_vec_ = NULL;						  \
									  \
  if (len_)								  \
    {									  \
1119 1120
      new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact		  \
			       (NULL, len_,				  \
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
				offsetof (VEC(T,A),base.vec), sizeof (T)  \
				PASS_MEM_STAT));			  \
									  \
      new_vec_->base.num = len_;					  \
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
    }									  \
  return new_vec_;							  \
}									  \
									  \
static inline void VEC_OP (T,A,free)					  \
     (VEC(T,A) **vec_)							  \
{									  \
  if (*vec_)								  \
    vec_##A##_free (*vec_);						  \
  *vec_ = NULL;								  \
}									  \
									  \
static inline int VEC_OP (T,A,reserve)	   	    			  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
1141
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
				       VEC_CHECK_PASS);			  \
									  \
  if (extend)								  \
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,		  \
			   		      offsetof (VEC(T,A),base.vec),\
 					      sizeof (T)		  \
			   		      PASS_MEM_STAT);		  \
									  \
  return extend;							  \
}									  \
									  \
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
static inline int VEC_OP (T,A,reserve_exact)   	    			  \
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_		  \
				       VEC_CHECK_PASS);			  \
									  \
  if (extend)								  \
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact			  \
			 (*vec_, alloc_, offsetof (VEC(T,A),base.vec),	  \
			  sizeof (T) PASS_MEM_STAT);			  \
									  \
  return extend;							  \
}									  \
									  \
1167 1168 1169 1170 1171 1172
static inline void VEC_OP (T,A,safe_grow)				  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  VEC_ASSERT (size_ >= 0						  \
	      && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
						 "grow", T, A);		  \
1173 1174 1175
  VEC_OP (T,A,reserve_exact) (vec_,					  \
			      size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
			      VEC_CHECK_PASS PASS_MEM_STAT);		  \
1176 1177 1178
  VEC_BASE (*vec_)->num = size_;					  \
}									  \
									  \
1179 1180 1181 1182 1183 1184 1185 1186 1187
static inline void VEC_OP (T,A,safe_grow_cleared)			  \
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
{									  \
  int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_);			  \
  VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT);	  \
  memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0,	  \
	  sizeof (T) * (size_ - oldsize));				  \
}									  \
									  \
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
static inline T *VEC_OP (T,A,safe_push)					  \
     (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL)	  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
}									  \
									  \
static inline T *VEC_OP (T,A,safe_insert)		     	  	  \
     (VEC(T,A) **vec_, unsigned ix_, const T obj_			  \
 		VEC_CHECK_DECL MEM_STAT_DECL)				  \
{									  \
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);		  \
									  \
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_	  \
				       VEC_CHECK_PASS);			  \
}

1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
/* We support a vector which starts out with space on the stack and
   switches to heap space when forced to reallocate.  This works a
   little differently.  Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use
   DEF_VEC_ALLOC_P_STACK(TYPE).  This uses alloca to get the initial
   space; because alloca can not be usefully called in an inline
   function, and because a macro can not define a macro, you must then
   write a #define for each type:

   #define VEC_{TYPE}_stack_alloc(alloc)                          \
     VEC_stack_alloc({TYPE}, alloc)

   This is really a hack and perhaps can be made better.  Note that
   this macro will wind up evaluating the ALLOC parameter twice.

   Only the initial allocation will be made using alloca, so pass a
   reasonable estimate that doesn't use too much stack space; don't
   pass zero.  Don't return a VEC(TYPE,stack) vector from the function
   which allocated it.  */

extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL);
extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL);
extern void *vec_stack_p_reserve_exact_1 (int, void *);
extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
					 MEM_STAT_DECL);
extern void vec_stack_free (void *);

1233 1234 1235 1236 1237
#ifdef GATHER_STATISTICS
#define VEC_stack_alloc(T,alloc,name,line,function)			  \
  (VEC_OP (T,stack,alloc1)						  \
   (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
#else
1238 1239 1240
#define VEC_stack_alloc(T,alloc)					  \
  (VEC_OP (T,stack,alloc1)						  \
   (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
1241
#endif
1242 1243 1244 1245 1246 1247 1248 1249 1250

#define DEF_VEC_ALLOC_P_STACK(T)					  \
VEC_TA(T,base,stack);							  \
DEF_VEC_ALLOC_FUNC_P_STACK(T)						  \
DEF_VEC_NONALLOC_FUNCS_P(T,stack)					  \
struct vec_swallow_trailing_semi

#define DEF_VEC_ALLOC_FUNC_P_STACK(T)					  \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1251
     (int alloc_, VEC(T,stack)* space)					  \
1252
{									  \
1253
  return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);	  \
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
}

#define DEF_VEC_ALLOC_O_STACK(T)					  \
VEC_TA(T,base,stack);							  \
DEF_VEC_ALLOC_FUNC_O_STACK(T)						  \
DEF_VEC_NONALLOC_FUNCS_O(T,stack)					  \
struct vec_swallow_trailing_semi

#define DEF_VEC_ALLOC_FUNC_O_STACK(T)					  \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1264
     (int alloc_, VEC(T,stack)* space)					  \
1265
{									  \
1266
  return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);	  \
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
}

#define DEF_VEC_ALLOC_I_STACK(T)					  \
VEC_TA(T,base,stack);							  \
DEF_VEC_ALLOC_FUNC_I_STACK(T)						  \
DEF_VEC_NONALLOC_FUNCS_I(T,stack)					  \
struct vec_swallow_trailing_semi

#define DEF_VEC_ALLOC_FUNC_I_STACK(T)					  \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1)			  \
1277
     (int alloc_, VEC(T,stack)* space)					  \
1278
{									  \
1279
  return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space);   \
1280 1281
}

1282
#endif /* GCC_VEC_H */