OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [vec.h] - Blame information for rev 248

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.