OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

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

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 251 jeremybenn
/* JPB 25-Aug-10: Derived vector type, user visible for anonymous
477
   struct. Gets rid of compile warnings. */
478
#define VEC_TA_GTY_ANON(T,B,A)                                            \
479
typedef struct VEC(T,A)                                                   \
480
{                                                                         \
481
  VEC(T,B) base;                                                          \
482
} VEC(T,A)
483
 
484 38 julius
/* Convert to base type.  */
485
#define VEC_BASE(P)  ((P) ? &(P)->base : 0)
486
 
487
/* Vector of integer-like object.  */
488
#if IN_GENGTYPE
489
{"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
490
{"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
491
#else
492
#define DEF_VEC_I(T)                                                      \
493
static inline void VEC_OP (T,must_be,integral_type) (void)                \
494
{                                                                         \
495
  (void)~(T)0;                                                             \
496
}                                                                         \
497
                                                                          \
498
VEC_T(T,base);                                                            \
499 251 jeremybenn
VEC_TA_GTY_ANON(T,base,none);                                             \
500 38 julius
DEF_VEC_FUNC_P(T)                                                         \
501
struct vec_swallow_trailing_semi
502
#define DEF_VEC_ALLOC_I(T,A)                                              \
503 251 jeremybenn
VEC_TA_GTY_ANON(T,base,A);                                                \
504 38 julius
DEF_VEC_ALLOC_FUNC_I(T,A)                                                 \
505
struct vec_swallow_trailing_semi
506
#endif
507
 
508
/* Vector of pointer to object.  */
509
#if IN_GENGTYPE
510
{"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
511
{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
512
#else
513
#define DEF_VEC_P(T)                                                      \
514
static inline void VEC_OP (T,must_be,pointer_type) (void)                 \
515
{                                                                         \
516
  (void)((T)1 == (void *)1);                                              \
517
}                                                                         \
518
                                                                          \
519
VEC_T_GTY(T,base);                                                        \
520 251 jeremybenn
VEC_TA_GTY_ANON(T,base,none);                                             \
521 38 julius
DEF_VEC_FUNC_P(T)                                                         \
522
struct vec_swallow_trailing_semi
523
#define DEF_VEC_ALLOC_P(T,A)                                              \
524 251 jeremybenn
VEC_TA_GTY_ANON(T,base,A);                                                        \
525 38 julius
DEF_VEC_ALLOC_FUNC_P(T,A)                                                 \
526
struct vec_swallow_trailing_semi
527
#endif
528
 
529
#define DEF_VEC_FUNC_P(T)                                                 \
530
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)   \
531
{                                                                         \
532
  return vec_ ? vec_->num : 0;                                             \
533
}                                                                         \
534
                                                                          \
535
static inline T VEC_OP (T,base,last)                                      \
536
     (const VEC(T,base) *vec_ VEC_CHECK_DECL)                             \
537
{                                                                         \
538
  VEC_ASSERT (vec_ && vec_->num, "last", T, base);                        \
539
                                                                          \
540
  return vec_->vec[vec_->num - 1];                                        \
541
}                                                                         \
542
                                                                          \
543
static inline T VEC_OP (T,base,index)                                     \
544
     (const VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)               \
545
{                                                                         \
546
  VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base);                 \
547
                                                                          \
548
  return vec_->vec[ix_];                                                  \
549
}                                                                         \
550
                                                                          \
551
static inline int VEC_OP (T,base,iterate)                                 \
552
     (const VEC(T,base) *vec_, unsigned ix_, T *ptr)                      \
553
{                                                                         \
554
  if (vec_ && ix_ < vec_->num)                                            \
555
    {                                                                     \
556
      *ptr = vec_->vec[ix_];                                              \
557
      return 1;                                                           \
558
    }                                                                     \
559
  else                                                                    \
560
    {                                                                     \
561
      *ptr = 0;                                                            \
562
      return 0;                                                            \
563
    }                                                                     \
564
}                                                                         \
565
                                                                          \
566
static inline size_t VEC_OP (T,base,embedded_size)                        \
567
     (int alloc_)                                                         \
568
{                                                                         \
569
  return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);                 \
570
}                                                                         \
571
                                                                          \
572
static inline void VEC_OP (T,base,embedded_init)                          \
573
     (VEC(T,base) *vec_, int alloc_)                                      \
574
{                                                                         \
575
  vec_->num = 0;                                                   \
576
  vec_->alloc = alloc_;                                                   \
577
}                                                                         \
578
                                                                          \
579
static inline int VEC_OP (T,base,space)                                   \
580
     (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)                       \
581
{                                                                         \
582
  VEC_ASSERT (alloc_ >= 0, "space", T, base);                              \
583
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;    \
584
}                                                                         \
585
                                                                          \
586
static inline T *VEC_OP (T,base,quick_push)                               \
587
     (VEC(T,base) *vec_, T obj_ VEC_CHECK_DECL)                           \
588
{                                                                         \
589
  T *slot_;                                                               \
590
                                                                          \
591
  VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base);                  \
592
  slot_ = &vec_->vec[vec_->num++];                                        \
593
  *slot_ = obj_;                                                          \
594
                                                                          \
595
  return slot_;                                                           \
596
}                                                                         \
597
                                                                          \
598
static inline T VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL)    \
599
{                                                                         \
600
  T obj_;                                                                 \
601
                                                                          \
602
  VEC_ASSERT (vec_->num, "pop", T, base);                                 \
603
  obj_ = vec_->vec[--vec_->num];                                          \
604
                                                                          \
605
  return obj_;                                                            \
606
}                                                                         \
607
                                                                          \
608
static inline void VEC_OP (T,base,truncate)                               \
609
     (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)                   \
610
{                                                                         \
611
  VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base);   \
612
  if (vec_)                                                               \
613
    vec_->num = size_;                                                    \
614
}                                                                         \
615
                                                                          \
616
static inline T VEC_OP (T,base,replace)                                   \
617
     (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)             \
618
{                                                                         \
619
  T old_obj_;                                                             \
620
                                                                          \
621
  VEC_ASSERT (ix_ < vec_->num, "replace", T, base);                       \
622
  old_obj_ = vec_->vec[ix_];                                              \
623
  vec_->vec[ix_] = obj_;                                                  \
624
                                                                          \
625
  return old_obj_;                                                        \
626
}                                                                         \
627
                                                                          \
628
static inline T *VEC_OP (T,base,quick_insert)                             \
629
     (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL)             \
630
{                                                                         \
631
  T *slot_;                                                               \
632
                                                                          \
633
  VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base);                \
634
  VEC_ASSERT (ix_ <= vec_->num, "insert", T, base);                       \
635
  slot_ = &vec_->vec[ix_];                                                \
636
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));           \
637
  *slot_ = obj_;                                                          \
638
                                                                          \
639
  return slot_;                                                           \
640
}                                                                         \
641
                                                                          \
642
static inline T VEC_OP (T,base,ordered_remove)                            \
643
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)                     \
644
{                                                                         \
645
  T *slot_;                                                               \
646
  T obj_;                                                                 \
647
                                                                          \
648
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);                        \
649
  slot_ = &vec_->vec[ix_];                                                \
650
  obj_ = *slot_;                                                          \
651
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));           \
652
                                                                          \
653
  return obj_;                                                            \
654
}                                                                         \
655
                                                                          \
656
static inline T VEC_OP (T,base,unordered_remove)                          \
657
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)                     \
658
{                                                                         \
659
  T *slot_;                                                               \
660
  T obj_;                                                                 \
661
                                                                          \
662
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);                        \
663
  slot_ = &vec_->vec[ix_];                                                \
664
  obj_ = *slot_;                                                          \
665
  *slot_ = vec_->vec[--vec_->num];                                        \
666
                                                                          \
667
  return obj_;                                                            \
668
}                                                                         \
669
                                                                          \
670
static inline void VEC_OP (T,base,block_remove)                           \
671
     (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)      \
672
{                                                                         \
673
  T *slot_;                                                               \
674
                                                                          \
675
  VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base);          \
676
  slot_ = &vec_->vec[ix_];                                                \
677
  vec_->num -= len_;                                                      \
678
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));          \
679
}                                                                         \
680
                                                                          \
681
static inline T *VEC_OP (T,base,address)                                  \
682
     (VEC(T,base) *vec_)                                                  \
683
{                                                                         \
684
  return vec_ ? vec_->vec : 0;                                             \
685
}                                                                         \
686
                                                                          \
687
static inline unsigned VEC_OP (T,base,lower_bound)                        \
688
     (VEC(T,base) *vec_, const T obj_,                                    \
689
      bool (*lessthan_)(const T, const T) VEC_CHECK_DECL)                 \
690
{                                                                         \
691
   unsigned int len_ = VEC_OP (T,base, length) (vec_);                    \
692
   unsigned int half_, middle_;                                           \
693
   unsigned int first_ = 0;                                                \
694
   while (len_ > 0)                                                        \
695
     {                                                                    \
696
        T middle_elem_;                                                   \
697
        half_ = len_ >> 1;                                                \
698
        middle_ = first_;                                                 \
699
        middle_ += half_;                                                 \
700
        middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
701
        if (lessthan_ (middle_elem_, obj_))                               \
702
          {                                                               \
703
             first_ = middle_;                                            \
704
             ++first_;                                                    \
705
             len_ = len_ - half_ - 1;                                     \
706
          }                                                               \
707
        else                                                              \
708
          len_ = half_;                                                   \
709
     }                                                                    \
710
   return first_;                                                         \
711
}
712
 
713
#define DEF_VEC_ALLOC_FUNC_P(T,A)                                         \
714
static inline VEC(T,A) *VEC_OP (T,A,alloc)                                \
715
     (int alloc_ MEM_STAT_DECL)                                           \
716
{                                                                         \
717
  return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_             \
718
                                                 PASS_MEM_STAT);          \
719
}                                                                         \
720
                                                                          \
721
static inline void VEC_OP (T,A,free)                                      \
722
     (VEC(T,A) **vec_)                                                    \
723
{                                                                         \
724
  if (*vec_)                                                              \
725
    vec_##A##_free (*vec_);                                               \
726
  *vec_ = NULL;                                                           \
727
}                                                                         \
728
                                                                          \
729
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
730
{                                                                         \
731
  size_t len_ = vec_ ? vec_->num : 0;                                      \
732
  VEC (T,A) *new_vec_ = NULL;                                             \
733
                                                                          \
734
  if (len_)                                                               \
735
    {                                                                     \
736
      new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact                  \
737
                               (NULL, len_ PASS_MEM_STAT));               \
738
                                                                          \
739
      new_vec_->base.num = len_;                                          \
740
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);          \
741
    }                                                                     \
742
  return new_vec_;                                                        \
743
}                                                                         \
744
                                                                          \
745
static inline int VEC_OP (T,A,reserve)                                    \
746
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
747
{                                                                         \
748
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
749
                                       VEC_CHECK_PASS);                   \
750
                                                                          \
751
  if (extend)                                                             \
752
    *vec_ = (VEC(T,A) *) vec_##A##_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \
753
                                                                          \
754
  return extend;                                                          \
755
}                                                                         \
756
                                                                          \
757
static inline int VEC_OP (T,A,reserve_exact)                              \
758
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
759
{                                                                         \
760
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
761
                                       VEC_CHECK_PASS);                   \
762
                                                                          \
763
  if (extend)                                                             \
764
    *vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_         \
765
                                                    PASS_MEM_STAT);       \
766
                                                                          \
767
  return extend;                                                          \
768
}                                                                         \
769
                                                                          \
770
static inline void VEC_OP (T,A,safe_grow)                                 \
771
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)            \
772
{                                                                         \
773
  VEC_ASSERT (size_ >= 0                                           \
774
              && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
775
                                                 "grow", T, A);           \
776
  VEC_OP (T,A,reserve_exact) (vec_,                                       \
777
                              size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
778
                              VEC_CHECK_PASS PASS_MEM_STAT);              \
779
  VEC_BASE (*vec_)->num = size_;                                          \
780
}                                                                         \
781
                                                                          \
782
static inline T *VEC_OP (T,A,safe_push)                                   \
783
     (VEC(T,A) **vec_, 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_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
788
}                                                                         \
789
                                                                          \
790
static inline T *VEC_OP (T,A,safe_insert)                                 \
791
     (VEC(T,A) **vec_, unsigned ix_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL)  \
792
{                                                                         \
793
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);            \
794
                                                                          \
795
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_         \
796
                                       VEC_CHECK_PASS);                   \
797
}
798
 
799
/* Vector of object.  */
800
#if IN_GENGTYPE
801
{"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
802
{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
803
#else
804
#define DEF_VEC_O(T)                                                      \
805
VEC_T_GTY(T,base);                                                        \
806 251 jeremybenn
VEC_TA_GTY_ANON(T,base,none);                                             \
807 38 julius
DEF_VEC_FUNC_O(T)                                                         \
808
struct vec_swallow_trailing_semi
809
#define DEF_VEC_ALLOC_O(T,A)                                              \
810 251 jeremybenn
VEC_TA_GTY_ANON(T,base,A);                                                \
811 38 julius
DEF_VEC_ALLOC_FUNC_O(T,A)                                                 \
812
struct vec_swallow_trailing_semi
813
#endif
814
 
815
#define DEF_VEC_FUNC_O(T)                                                 \
816
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)   \
817
{                                                                         \
818
  return vec_ ? vec_->num : 0;                                             \
819
}                                                                         \
820
                                                                          \
821
static inline T *VEC_OP (T,base,last) (VEC(T,base) *vec_ VEC_CHECK_DECL)  \
822
{                                                                         \
823
  VEC_ASSERT (vec_ && vec_->num, "last", T, base);                        \
824
                                                                          \
825
  return &vec_->vec[vec_->num - 1];                                       \
826
}                                                                         \
827
                                                                          \
828
static inline T *VEC_OP (T,base,index)                                    \
829
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)                     \
830
{                                                                         \
831
  VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base);                 \
832
                                                                          \
833
  return &vec_->vec[ix_];                                                 \
834
}                                                                         \
835
                                                                          \
836
static inline int VEC_OP (T,base,iterate)                                 \
837
     (VEC(T,base) *vec_, unsigned ix_, T **ptr)                           \
838
{                                                                         \
839
  if (vec_ && ix_ < vec_->num)                                            \
840
    {                                                                     \
841
      *ptr = &vec_->vec[ix_];                                             \
842
      return 1;                                                           \
843
    }                                                                     \
844
  else                                                                    \
845
    {                                                                     \
846
      *ptr = 0;                                                            \
847
      return 0;                                                            \
848
    }                                                                     \
849
}                                                                         \
850
                                                                          \
851
static inline size_t VEC_OP (T,base,embedded_size)                        \
852
     (int alloc_)                                                         \
853
{                                                                         \
854
  return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T);                 \
855
}                                                                         \
856
                                                                          \
857
static inline void VEC_OP (T,base,embedded_init)                          \
858
     (VEC(T,base) *vec_, int alloc_)                                      \
859
{                                                                         \
860
  vec_->num = 0;                                                   \
861
  vec_->alloc = alloc_;                                                   \
862
}                                                                         \
863
                                                                          \
864
static inline int VEC_OP (T,base,space)                                   \
865
     (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL)                       \
866
{                                                                         \
867
  VEC_ASSERT (alloc_ >= 0, "space", T, base);                              \
868
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;    \
869
}                                                                         \
870
                                                                          \
871
static inline T *VEC_OP (T,base,quick_push)                               \
872
     (VEC(T,base) *vec_, const T *obj_ VEC_CHECK_DECL)                    \
873
{                                                                         \
874
  T *slot_;                                                               \
875
                                                                          \
876
  VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base);                  \
877
  slot_ = &vec_->vec[vec_->num++];                                        \
878
  if (obj_)                                                               \
879
    *slot_ = *obj_;                                                       \
880
                                                                          \
881
  return slot_;                                                           \
882
}                                                                         \
883
                                                                          \
884
static inline void VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
885
{                                                                         \
886
  VEC_ASSERT (vec_->num, "pop", T, base);                                 \
887
  --vec_->num;                                                            \
888
}                                                                         \
889
                                                                          \
890
static inline void VEC_OP (T,base,truncate)                               \
891
     (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL)                   \
892
{                                                                         \
893
  VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base);   \
894
  if (vec_)                                                               \
895
    vec_->num = size_;                                                    \
896
}                                                                         \
897
                                                                          \
898
static inline T *VEC_OP (T,base,replace)                                  \
899
     (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)      \
900
{                                                                         \
901
  T *slot_;                                                               \
902
                                                                          \
903
  VEC_ASSERT (ix_ < vec_->num, "replace", T, base);                       \
904
  slot_ = &vec_->vec[ix_];                                                \
905
  if (obj_)                                                               \
906
    *slot_ = *obj_;                                                       \
907
                                                                          \
908
  return slot_;                                                           \
909
}                                                                         \
910
                                                                          \
911
static inline T *VEC_OP (T,base,quick_insert)                             \
912
     (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL)      \
913
{                                                                         \
914
  T *slot_;                                                               \
915
                                                                          \
916
  VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base);                \
917
  VEC_ASSERT (ix_ <= vec_->num, "insert", T, base);                       \
918
  slot_ = &vec_->vec[ix_];                                                \
919
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));           \
920
  if (obj_)                                                               \
921
    *slot_ = *obj_;                                                       \
922
                                                                          \
923
  return slot_;                                                           \
924
}                                                                         \
925
                                                                          \
926
static inline void VEC_OP (T,base,ordered_remove)                         \
927
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)                     \
928
{                                                                         \
929
  T *slot_;                                                               \
930
                                                                          \
931
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);                        \
932
  slot_ = &vec_->vec[ix_];                                                \
933
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));           \
934
}                                                                         \
935
                                                                          \
936
static inline void VEC_OP (T,base,unordered_remove)                       \
937
     (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL)                     \
938
{                                                                         \
939
  VEC_ASSERT (ix_ < vec_->num, "remove", T, base);                        \
940
  vec_->vec[ix_] = vec_->vec[--vec_->num];                                \
941
}                                                                         \
942
                                                                          \
943
static inline void VEC_OP (T,base,block_remove)                           \
944
     (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL)      \
945
{                                                                         \
946
  T *slot_;                                                               \
947
                                                                          \
948
  VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base);          \
949
  slot_ = &vec_->vec[ix_];                                                \
950
  vec_->num -= len_;                                                      \
951
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));          \
952
}                                                                         \
953
                                                                          \
954
static inline T *VEC_OP (T,base,address)                                  \
955
     (VEC(T,base) *vec_)                                                  \
956
{                                                                         \
957
  return vec_ ? vec_->vec : 0;                                             \
958
}                                                                         \
959
                                                                          \
960
static inline unsigned VEC_OP (T,base,lower_bound)                        \
961
     (VEC(T,base) *vec_, const T *obj_,                                   \
962
      bool (*lessthan_)(const T *, const T *) VEC_CHECK_DECL)             \
963
{                                                                         \
964
   unsigned int len_ = VEC_OP (T, base, length) (vec_);                   \
965
   unsigned int half_, middle_;                                           \
966
   unsigned int first_ = 0;                                                \
967
   while (len_ > 0)                                                        \
968
     {                                                                    \
969
        T *middle_elem_;                                                  \
970
        half_ = len_ >> 1;                                                \
971
        middle_ = first_;                                                 \
972
        middle_ += half_;                                                 \
973
        middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
974
        if (lessthan_ (middle_elem_, obj_))                               \
975
          {                                                               \
976
             first_ = middle_;                                            \
977
             ++first_;                                                    \
978
             len_ = len_ - half_ - 1;                                     \
979
          }                                                               \
980
        else                                                              \
981
          len_ = half_;                                                   \
982
     }                                                                    \
983
   return first_;                                                         \
984
}
985
 
986
#define DEF_VEC_ALLOC_FUNC_O(T,A)                                         \
987
static inline VEC(T,A) *VEC_OP (T,A,alloc)                                \
988
     (int alloc_ MEM_STAT_DECL)                                           \
989
{                                                                         \
990
  return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_,            \
991
                                                 offsetof (VEC(T,A),base.vec), \
992
                                                 sizeof (T)               \
993
                                                 PASS_MEM_STAT);          \
994
}                                                                         \
995
                                                                          \
996
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
997
{                                                                         \
998
  size_t len_ = vec_ ? vec_->num : 0;                                      \
999
  VEC (T,A) *new_vec_ = NULL;                                             \
1000
                                                                          \
1001
  if (len_)                                                               \
1002
    {                                                                     \
1003
      new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact                  \
1004
                               (NULL, len_,                               \
1005
                                offsetof (VEC(T,A),base.vec), sizeof (T)  \
1006
                                PASS_MEM_STAT));                          \
1007
                                                                          \
1008
      new_vec_->base.num = len_;                                          \
1009
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);          \
1010
    }                                                                     \
1011
  return new_vec_;                                                        \
1012
}                                                                         \
1013
                                                                          \
1014
static inline void VEC_OP (T,A,free)                                      \
1015
     (VEC(T,A) **vec_)                                                    \
1016
{                                                                         \
1017
  if (*vec_)                                                              \
1018
    vec_##A##_free (*vec_);                                               \
1019
  *vec_ = NULL;                                                           \
1020
}                                                                         \
1021
                                                                          \
1022
static inline int VEC_OP (T,A,reserve)                                    \
1023
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
1024
{                                                                         \
1025
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
1026
                                       VEC_CHECK_PASS);                   \
1027
                                                                          \
1028
  if (extend)                                                             \
1029
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,              \
1030
                                              offsetof (VEC(T,A),base.vec),\
1031
                                              sizeof (T)                  \
1032
                                              PASS_MEM_STAT);             \
1033
                                                                          \
1034
  return extend;                                                          \
1035
}                                                                         \
1036
                                                                          \
1037
static inline int VEC_OP (T,A,reserve_exact)                              \
1038
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
1039
{                                                                         \
1040
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
1041
                                       VEC_CHECK_PASS);                   \
1042
                                                                          \
1043
  if (extend)                                                             \
1044
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact                        \
1045
                         (*vec_, alloc_,                                  \
1046
                          offsetof (VEC(T,A),base.vec),                   \
1047
                          sizeof (T) PASS_MEM_STAT);                      \
1048
                                                                          \
1049
  return extend;                                                          \
1050
}                                                                         \
1051
                                                                          \
1052
static inline void VEC_OP (T,A,safe_grow)                                 \
1053
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)            \
1054
{                                                                         \
1055
  VEC_ASSERT (size_ >= 0                                           \
1056
              && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
1057
                                                 "grow", T, A);           \
1058
  VEC_OP (T,A,reserve_exact) (vec_,                                       \
1059
                              size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
1060
                              VEC_CHECK_PASS PASS_MEM_STAT);              \
1061
  VEC_BASE (*vec_)->num = size_;                                          \
1062
}                                                                         \
1063
                                                                          \
1064
static inline T *VEC_OP (T,A,safe_push)                                   \
1065
     (VEC(T,A) **vec_, const T *obj_ VEC_CHECK_DECL MEM_STAT_DECL)        \
1066
{                                                                         \
1067
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);            \
1068
                                                                          \
1069
  return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
1070
}                                                                         \
1071
                                                                          \
1072
static inline T *VEC_OP (T,A,safe_insert)                                 \
1073
     (VEC(T,A) **vec_, unsigned ix_, const T *obj_                        \
1074
                VEC_CHECK_DECL MEM_STAT_DECL)                             \
1075
{                                                                         \
1076
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);            \
1077
                                                                          \
1078
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_         \
1079
                                       VEC_CHECK_PASS);                   \
1080
}
1081
 
1082
#define DEF_VEC_ALLOC_FUNC_I(T,A)                                         \
1083
static inline VEC(T,A) *VEC_OP (T,A,alloc)                                \
1084
     (int alloc_ MEM_STAT_DECL)                                           \
1085
{                                                                         \
1086
  return (VEC(T,A) *) vec_##A##_o_reserve_exact                           \
1087
                      (NULL, alloc_, offsetof (VEC(T,A),base.vec),        \
1088
                       sizeof (T) PASS_MEM_STAT);                         \
1089
}                                                                         \
1090
                                                                          \
1091
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
1092
{                                                                         \
1093
  size_t len_ = vec_ ? vec_->num : 0;                                      \
1094
  VEC (T,A) *new_vec_ = NULL;                                             \
1095
                                                                          \
1096
  if (len_)                                                               \
1097
    {                                                                     \
1098
      new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact                  \
1099
                               (NULL, len_,                               \
1100
                                offsetof (VEC(T,A),base.vec), sizeof (T)  \
1101
                                PASS_MEM_STAT));                          \
1102
                                                                          \
1103
      new_vec_->base.num = len_;                                          \
1104
      memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);          \
1105
    }                                                                     \
1106
  return new_vec_;                                                        \
1107
}                                                                         \
1108
                                                                          \
1109
static inline void VEC_OP (T,A,free)                                      \
1110
     (VEC(T,A) **vec_)                                                    \
1111
{                                                                         \
1112
  if (*vec_)                                                              \
1113
    vec_##A##_free (*vec_);                                               \
1114
  *vec_ = NULL;                                                           \
1115
}                                                                         \
1116
                                                                          \
1117
static inline int VEC_OP (T,A,reserve)                                    \
1118
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
1119
{                                                                         \
1120
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
1121
                                       VEC_CHECK_PASS);                   \
1122
                                                                          \
1123
  if (extend)                                                             \
1124
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_,              \
1125
                                              offsetof (VEC(T,A),base.vec),\
1126
                                              sizeof (T)                  \
1127
                                              PASS_MEM_STAT);             \
1128
                                                                          \
1129
  return extend;                                                          \
1130
}                                                                         \
1131
                                                                          \
1132
static inline int VEC_OP (T,A,reserve_exact)                              \
1133
     (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)           \
1134
{                                                                         \
1135
  int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_            \
1136
                                       VEC_CHECK_PASS);                   \
1137
                                                                          \
1138
  if (extend)                                                             \
1139
    *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact                        \
1140
                         (*vec_, alloc_, offsetof (VEC(T,A),base.vec),    \
1141
                          sizeof (T) PASS_MEM_STAT);                      \
1142
                                                                          \
1143
  return extend;                                                          \
1144
}                                                                         \
1145
                                                                          \
1146
static inline void VEC_OP (T,A,safe_grow)                                 \
1147
     (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL)            \
1148
{                                                                         \
1149
  VEC_ASSERT (size_ >= 0                                           \
1150
              && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
1151
                                                 "grow", T, A);           \
1152
  VEC_OP (T,A,reserve_exact) (vec_,                                       \
1153
                              size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
1154
                              VEC_CHECK_PASS PASS_MEM_STAT);              \
1155
  VEC_BASE (*vec_)->num = size_;                                          \
1156
}                                                                         \
1157
                                                                          \
1158
static inline T *VEC_OP (T,A,safe_push)                                   \
1159
     (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL)         \
1160
{                                                                         \
1161
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);            \
1162
                                                                          \
1163
  return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS);  \
1164
}                                                                         \
1165
                                                                          \
1166
static inline T *VEC_OP (T,A,safe_insert)                                 \
1167
     (VEC(T,A) **vec_, unsigned ix_, const T obj_                         \
1168
                VEC_CHECK_DECL MEM_STAT_DECL)                             \
1169
{                                                                         \
1170
  VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT);            \
1171
                                                                          \
1172
  return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_         \
1173
                                       VEC_CHECK_PASS);                   \
1174
}
1175
 
1176
#endif /* GCC_VEC_H */

powered by: WebSVN 2.1.0

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