OSDN Git Service

* vec.h (VEC_T_safe_push, VEC_T_safe_insert): Tweak for when
[pf3gnuchains/gcc-fork.git] / gcc / vec.h
1 /* Vector API for GNU compiler.
2    Copyright (C) 2004 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 2, 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 COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #ifndef GCC_VEC_H
23 #define GCC_VEC_H
24
25 /* The macros here implement a set of templated vector types and
26    associated interfaces.  These templates are implemented with
27    macros, as we're not in C++ land.  The interface functions are
28    typesafe and use static inline functions, sometimes backed by
29    out-of-line generic functions.  The vectors are designed to
30    interoperate with the GTY machinery.
31
32    Because of the different behaviour of objects and of pointers to
33    objects, there are two flavours.  One to deal with a vector of
34    pointers to objects, and one to deal with a vector of objects
35    themselves.  Both of these pass pointers to objects around -- in
36    the former case the pointers are stored into the vector and in the
37    latter case the pointers are dereferenced and the objects copied
38    into the vector.  Therefore, when using a vector of pointers, the
39    objects pointed to must be long lived, but when dealing with a
40    vector of objects, the source objects need not be.
41
42    The vectors are implemented using the trailing array idiom, thus
43    they are not resizeable without changing the address of the vector
44    object itself.  This means you cannot have variables or fields of
45    vector type -- always use a pointer to a vector.  The one exception
46    is the final field of a structure, which could be a vector type.
47    You will have to use the embedded_alloc call to create such
48    objects, and they will probably not be resizeable (so don't use the
49    'safe' allocation variants).  The trailing array idiom is used
50    (rather than a pointer to an array of data), because, if we allow
51    NULL to also represent an empty vector, empty vectors occupy
52    minimal space in the structure containing them.
53
54    Each operation that increases the number of active elements is
55    available in 'quick' and 'safe' variants.  The former presumes that
56    there is sufficient allocated space for the operation to succeed
57    (it aborts if there is not).  The latter will reallocate the
58    vector, if needed.  Reallocation causes an exponential increase in
59    vector size.  If you know you will be adding N elements, it would
60    be more efficient to use the reserve operation before adding the
61    elements with the 'quick' operation.
62
63    You should prefer the push and pop operations, as they append and
64    remove from the end of the vector.  The insert and remove
65    operations allow you to change elements in the middle of the
66    vector.  There are two remove operations, one which preserves the
67    element ordering 'ordered_remove', and one which does not
68    'unordered_remove'.  The latter function copies the end element
69    into the removed slot, rather than invoke a memmove operation.
70    
71    Vector types are defined using a DEF_VEC_x(TYPEDEF) macro, and
72    variables of vector type are declared using a VEC(TYPEDEF)
73    macro. The 'x' letter indicates whether TYPEDEF is a pointer (P) or
74    object (O) type.
75
76    An example of their use would be,
77
78    DEF_VEC_P(tree);     // define a vector of tree pointers.  This must
79                         // appear at file scope.
80
81    struct my_struct {
82      VEC(tree) *v;      // A (pointer to) a vector of tree pointers.
83    };
84
85    struct my_struct *s;
86
87    if (VEC_length(tree,s)) { we have some contents }
88    VEC_safe_push(tree,s,decl); // append some decl onto the end
89    for (ix = 0; (t = VEC_iterate(tree,s,ix)); ix++)
90      { do something with t }
91
92 */
93
94 /* Macros to invoke API calls.  A single macro works for both pointer
95    and object vectors, but the argument and return types might well be
96    different.  In each macro, TDEF is the typedef of the vector
97    elements.  Some of these macros pass the vector, V, by reference
98    (by taking its address), this is noted in the descriptions.  */
99
100 /* Length of vector
101    size_t VEC_T_length(const VEC(T) *v);
102
103    Return the number of active elements in V.  V can be NULL, in which
104    case zero is returned.  */
105 #define VEC_length(TDEF,V)              (VEC_OP(TDEF,length)(V))
106
107 /* Get the final element of the vector.
108    T VEC_T_last(VEC(T) *v); // Pointer
109    T *VEC_T_last(VEC(T) *v); // Object
110
111    Return the final element.  If V is empty,  abort.  */
112 #define VEC_last(TDEF,V)                (VEC_OP(TDEF,last)(V))
113
114 /* Index into vector
115    T VEC_T_index(VEC(T) *v, size_t ix); // Pointer
116    T *VEC_T_index(VEC(T) *v, size_t ix); // Object
117
118    Return the IX'th element.  If IX is outside the domain of V,
119    abort.  */
120 #define VEC_index(TDEF,V,I)             (VEC_OP(TDEF,index)(V,I))
121
122 /* Iterate over vector
123    T VEC_T_index(VEC(T) *v, size_t ix); // Pointer
124    T *VEC_T_index(VEC(T) *v, size_t ix); // Object
125
126    Return the IX'th element or NULL. Use this to iterate over the
127    elements of a vector as follows,
128
129      for (ix = 0; (ptr = VEC_iterate(T,v,ix)); ix++)
130        continue;  */
131 #define VEC_iterate(TDEF,V,I)           (VEC_OP(TDEF,iterate)(V,I))
132
133 /* Allocate new vector.
134    VEC(T) *VEC_T_alloc(size_t reserve);
135
136    Allocate a new vector with space for RESERVE objects.  */
137 #define VEC_alloc(TDEF,A)               (VEC_OP(TDEF,alloc)(A))
138
139 /* Allocate new vector offset within a structure
140    void *VEC_T_embedded_alloc(size_t offset, size_t reserve);
141
142    Allocate a new vector which is at offset OFFSET within a structure,
143    and with space for RESERVE objects.  Return a pointer to the start
144    of the structure containing the vector.  Naturally, the vector must
145    be the last member of the structure.  */
146 #define VEC_embedded_alloc(TDEF,O,A)    (VEC_OP(TDEF,embedded_alloc)(O,A))
147
148 /* Reserve space.
149    void VEC_T_reserve(VEC(T) *&v, size_t reserve);
150
151    Ensure that V has at least RESERVE slots available.  Note this can
152    cause V to be reallocated.  */
153 #define VEC_reserve(TDEF,V,R)           (VEC_OP(TDEF,reserve)(&(V),R))
154
155 /* Push object with no reallocation
156    T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
157    T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
158    
159    Push a new element onto the end, returns a pointer to the slot
160    filled in. For object vectors, the new value can be NULL, in which
161    case NO initialization is performed.  Aborts if there is
162    insufficient space in the vector. */
163 #define VEC_quick_push(TDEF,V,O)        (VEC_OP(TDEF,quick_push)(V,O))
164
165 /* Push object with reallocation
166    T *VEC_T_safe_push (VEC(T) *&v, T obj); // Pointer
167    T *VEC_T_safe_push (VEC(T) *&v, T *obj); // Object
168    
169    Push a new element onto the end, returns a pointer to the slot
170    filled in. For object vectors, the new value can be NULL, in which
171    case NO initialization is performed.  Reallocates V, if needed.  */
172 #define VEC_safe_push(TDEF,V,O)         (VEC_OP(TDEF,safe_push)(&(V),O))
173
174 /* Pop element off end
175    T VEC_T_pop (VEC(T) *v);             // Pointer
176    void VEC_T_pop (VEC(T) *v);          // Object
177
178    Pop the last element off the end. Returns the element popped, for
179    pointer vectors.  */
180 #define VEC_pop(TDEF,V)                 (VEC_OP(TDEF,pop)(V))
181
182 /* Replace element
183    T VEC_T_replace (VEC(T) *v, size_t ix, T val); // Pointer
184    T *VEC_T_replace (VEC(T) *v, size_t ix, T *val);  // Object
185    
186    Replace the IXth element of V with a new value, VAL.  For pointer
187    vectors returns the original value. For object vectors returns a
188    pointer to the new value.  For object vectors the new value can be
189    NULL, in which case no overwriting of the slot is actually
190    performed.  */
191 #define VEC_replace(TDEF,V,I,O)         (VEC_OP(TDEF,replace)(V,I,O))
192
193 /* Insert object with no reallocation
194    T *VEC_T_quick_insert (VEC(T) *v, size_t ix, T val); // Pointer
195    T *VEC_T_quick_insert (VEC(T) *v, size_t ix, T *val); // Object
196    
197    Insert an element, VAL, at the IXth position of V. Return a pointer
198    to the slot created.  For vectors of object, the new value can be
199    NULL, in which case no initialization of the inserted slot takes
200    place. Aborts if there is insufficient space.  */
201 #define VEC_quick_insert(TDEF,V,I,O)    (VEC_OP(TDEF,quick_insert)(V,I,O))
202
203 /* Insert object with reallocation
204    T *VEC_T_safe_insert (VEC(T) *&v, size_t ix, T val); // Pointer
205    T *VEC_T_safe_insert (VEC(T) *&v, size_t ix, T *val); // Object
206    
207    Insert an element, VAL, at the IXth position of V. Return a pointer
208    to the slot created.  For vectors of object, the new value can be
209    NULL, in which case no initialization of the inserted slot takes
210    place. Reallocate V, if necessary.  */
211 #define VEC_safe_insert(TDEF,V,I,O)     (VEC_OP(TDEF,safe_insert)(&(V),I,O))
212      
213 /* Remove element retaining order
214    T VEC_T_ordered_remove (VEC(T) *v, size_t ix); // Pointer
215    void VEC_T_ordered_remove (VEC(T) *v, size_t ix); // Object
216    
217    Remove an element from the IXth position of V. Ordering of
218    remaining elements is preserverd.  For pointer vectors returns the
219    removed object.  This is an O(N) operation due to a memmove.  */
220 #define VEC_ordered_remove(TDEF,V,I)    (VEC_OP(TDEF,ordered_remove)(V,I))
221
222 /* Remove element destroying order
223    T VEC_T_unordered_remove (VEC(T) *v, size_t ix); // Pointer
224    void VEC_T_unordered_remove (VEC(T) *v, size_t ix); // Object
225    
226    Remove an element from the IXth position of V. Ordering of
227    remaining elements is destroyed.  For pointer vectors returns the
228    removed object.  This is an O(1) operation.  */
229 #define VEC_unordered_remove(TDEF,V,I)  (VEC_OP(TDEF,unordered_remove)(V,I))
230
231 #if !IN_GENGTYPE
232 #include "auto-host.h"
233
234 /* Reallocate an array of elements with prefix.  */
235 extern void *vec_p_reserve (void *, size_t);
236 extern void *vec_o_reserve (void *, size_t, size_t, size_t);
237 extern void *vec_embedded_alloc (size_t, size_t, size_t, size_t);
238
239 #if ENABLE_CHECKING
240 extern void vec_assert_fail (const char *, const char *,
241                             const char *, size_t, const char *)
242      ATTRIBUTE_NORETURN;
243 #define VEC_ASSERT_FAIL(OP,VEC) \
244   vec_assert_fail (OP,#VEC,__FILE__,__LINE__,__FUNCTION__)
245      
246 #define VEC_ASSERT(EXPR,OP,TDEF) \
247   (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(TDEF)), 0))
248 #else
249 #define VEC_ASSERT(EXPR,OP,TYPE) (void)(EXPR)
250 #endif
251
252 #define VEC(TDEF) VEC_##TDEF
253 #define VEC_OP(TDEF,OP) VEC_OP_(VEC(TDEF),OP)
254 #define VEC_OP_(VEC,OP) VEC_OP__(VEC,OP)
255 #define VEC_OP__(VEC,OP) VEC ## _ ## OP
256 #else  /* IN_GENGTYPE */
257 #define VEC(TDEF) VEC_ TDEF
258 #define VEC_STRINGIFY(X) VEC_STRINGIFY_(X)
259 #define VEC_STRINGIFY_(X) #X
260 #undef GTY
261 #endif /* IN_GENGTYPE */
262
263 #define VEC_TDEF(TDEF)                                                    \
264 typedef struct VEC (TDEF) GTY(())                                         \
265 {                                                                         \
266   size_t num;                                                             \
267   size_t alloc;                                                           \
268   TDEF GTY ((length ("%h.num"))) vec[1];                                  \
269 } VEC (TDEF)
270
271 /* Vector of pointer to object.  */
272 #if IN_GENGTYPE
273 {"DEF_VEC_P", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
274 #else
275   
276 #define DEF_VEC_P(TDEF)                                                   \
277 VEC_TDEF (TDEF);                                                          \
278                                                                           \
279 static inline size_t VEC_OP (TDEF,length)                                 \
280      (const VEC (TDEF) *vec_)                                             \
281 {                                                                         \
282   return vec_ ? vec_->num : 0;                                            \
283 }                                                                         \
284                                                                           \
285 static inline TDEF VEC_OP (TDEF,last)                                     \
286      (const VEC (TDEF) *vec_)                                             \
287 {                                                                         \
288   VEC_ASSERT (vec_ && vec_->num, "last", TDEF);                           \
289                                                                           \
290   return vec_->vec[vec_->num - 1];                                        \
291 }                                                                         \
292                                                                           \
293 static inline TDEF VEC_OP (TDEF,index)                                    \
294      (const VEC (TDEF) *vec_, size_t ix_)                                 \
295 {                                                                         \
296   VEC_ASSERT (vec_ && ix_ < vec_->num, "index", TDEF);                    \
297                                                                           \
298   return vec_->vec[ix_];                                                  \
299 }                                                                         \
300                                                                           \
301 static inline TDEF VEC_OP (TDEF,iterate)                                  \
302      (const VEC (TDEF) *vec_, size_t ix_)                                 \
303 {                                                                         \
304   return vec_ && ix_ < vec_->num ? vec_->vec[ix_] : NULL;                 \
305 }                                                                         \
306                                                                           \
307 static inline VEC (TDEF) *VEC_OP (TDEF,alloc)                             \
308      (size_t alloc_)                                                      \
309 {                                                                         \
310   return vec_p_reserve (NULL, alloc_ - !alloc_);                          \
311 }                                                                         \
312                                                                           \
313 static inline void *VEC_OP (TDEF,embedded_alloc)                          \
314      (size_t offset_, size_t alloc_)                                      \
315 {                                                                         \
316   return vec_embedded_alloc (offset_, offsetof (VEC(TDEF),vec),           \
317                              sizeof (TDEF), alloc_);                      \
318 }                                                                         \
319                                                                           \
320 static inline void VEC_OP (TDEF,reserve)                                  \
321      (VEC (TDEF) **vec_, size_t alloc_)                                   \
322 {                                                                         \
323   *vec_ = vec_p_reserve (*vec_, alloc_);                                  \
324 }                                                                         \
325                                                                           \
326 static inline TDEF *VEC_OP (TDEF,quick_push)                              \
327      (VEC (TDEF) *vec_, TDEF obj_)                                        \
328 {                                                                         \
329   TDEF *slot_;                                                            \
330                                                                           \
331   VEC_ASSERT (vec_->num < vec_->alloc, "push", TDEF);                     \
332   slot_ = &vec_->vec[vec_->num++];                                        \
333   *slot_ = obj_;                                                          \
334                                                                           \
335   return slot_;                                                           \
336 }                                                                         \
337                                                                           \
338 static inline TDEF *VEC_OP (TDEF,safe_push)                               \
339      (VEC (TDEF) **vec_, TDEF obj_)                                       \
340 {                                                                         \
341   if (!*vec_ || (*vec_)->num == (*vec_)->alloc)                           \
342     VEC_OP (TDEF,reserve) (vec_, ~(size_t)0);                             \
343                                                                           \
344   return VEC_OP (TDEF,quick_push) (*vec_, obj_);                          \
345 }                                                                         \
346                                                                           \
347 static inline TDEF VEC_OP (TDEF,pop)                                      \
348      (VEC (TDEF) *vec_)                                                   \
349 {                                                                         \
350   TDEF obj_;                                                              \
351                                                                           \
352   VEC_ASSERT (vec_->num, "pop", TDEF);                                    \
353   obj_ = vec_->vec[--vec_->num];                                          \
354                                                                           \
355   return obj_;                                                            \
356 }                                                                         \
357                                                                           \
358 static inline TDEF VEC_OP (TDEF,replace)                                  \
359      (VEC (TDEF) *vec_, size_t ix_, TDEF obj_)                            \
360 {                                                                         \
361   TDEF old_obj_;                                                          \
362                                                                           \
363   VEC_ASSERT (ix_ < vec_->num, "replace", TDEF);                          \
364   old_obj_ = vec_->vec[ix_];                                              \
365   vec_->vec[ix_] = obj_;                                                  \
366                                                                           \
367   return old_obj_;                                                        \
368 }                                                                         \
369                                                                           \
370 static inline TDEF *VEC_OP (TDEF,quick_insert)                            \
371      (VEC (TDEF) *vec_, size_t ix_, TDEF obj_)                            \
372 {                                                                         \
373   TDEF *slot_;                                                            \
374                                                                           \
375   VEC_ASSERT (vec_->num < vec_->alloc, "insert", TDEF);                   \
376   VEC_ASSERT (ix_ <= vec_->num, "insert", TDEF);                          \
377   slot_ = &vec_->vec[ix_];                                                \
378   memmove (slot_ + 1, slot_, vec_->num++ - ix_);                          \
379   *slot_ = obj_;                                                          \
380                                                                           \
381   return slot_;                                                           \
382 }                                                                         \
383                                                                           \
384 static inline TDEF *VEC_OP (TDEF,safe_insert)                             \
385      (VEC (TDEF) **vec_, size_t ix_, TDEF obj_)                           \
386 {                                                                         \
387   if (!*vec_ || (*vec_)->num == (*vec_)->alloc)                           \
388     VEC_OP (TDEF,reserve) (vec_, ~(size_t)0);                             \
389                                                                           \
390   return VEC_OP (TDEF,quick_insert) (*vec_, ix_, obj_);                   \
391 }                                                                         \
392                                                                           \
393 static inline TDEF VEC_OP (TDEF,ordered_remove)                           \
394      (VEC (TDEF) *vec_, size_t ix_)                                       \
395 {                                                                         \
396   TDEF *slot_;                                                            \
397   TDEF obj_;                                                              \
398                                                                           \
399   VEC_ASSERT (ix_ < vec_->num, "remove", TDEF);                           \
400   slot_ = &vec_->vec[ix_];                                                \
401   obj_ = *slot_;                                                          \
402   memmove (slot_, slot_ + 1, --vec_->num - ix_);                          \
403                                                                           \
404   return obj_;                                                            \
405 }                                                                         \
406                                                                           \
407 static inline TDEF VEC_OP (TDEF,unordered_remove)                         \
408      (VEC (TDEF) *vec_, size_t ix_)                                       \
409 {                                                                         \
410   TDEF *slot_;                                                            \
411   TDEF obj_;                                                              \
412                                                                           \
413   VEC_ASSERT (ix_ < vec_->num, "remove", TDEF);                           \
414   slot_ = &vec_->vec[ix_];                                                \
415   obj_ = *slot_;                                                          \
416   *slot_ = vec_->vec[--vec_->num];                                        \
417                                                                           \
418   return obj_;                                                            \
419 }                                                                         \
420                                                                           \
421 struct vec_swallow_trailing_semi
422 #endif
423
424 /* Vector of object.  */
425 #if IN_GENGTYPE
426 {"DEF_VEC_O", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
427 #else
428   
429 #define DEF_VEC_O(TDEF)                                                   \
430 VEC_TDEF (TDEF);                                                          \
431                                                                           \
432 static inline size_t VEC_OP (TDEF,length)                                 \
433      (const VEC (TDEF) *vec_)                                             \
434 {                                                                         \
435   return vec_ ? vec_->num : 0;                                            \
436 }                                                                         \
437                                                                           \
438 static inline TDEF *VEC_OP (TDEF,last)                                    \
439      (VEC (TDEF) *vec_)                                                   \
440 {                                                                         \
441   VEC_ASSERT (vec_ && vec_->num, "last", TDEF);                           \
442                                                                           \
443   return &vec_->vec[vec_->num - 1];                                       \
444 }                                                                         \
445                                                                           \
446 static inline TDEF *VEC_OP (TDEF,index)                                   \
447      (VEC (TDEF) *vec_, size_t ix_)                                       \
448 {                                                                         \
449   VEC_ASSERT (vec_ && ix_ < vec_->num, "index", TDEF);                    \
450                                                                           \
451   return &vec_->vec[ix_];                                                 \
452 }                                                                         \
453                                                                           \
454 static inline TDEF *VEC_OP (TDEF,iterate)                                 \
455      (VEC (TDEF) *vec_, size_t ix_)                                       \
456 {                                                                         \
457   return vec_ && ix_ < vec_->num ? &vec_->vec[ix_] : NULL;                \
458 }                                                                         \
459                                                                           \
460 static inline VEC (TDEF) *VEC_OP (TDEF,alloc)                             \
461      (size_t alloc_)                                                      \
462 {                                                                         \
463   return vec_o_reserve (NULL, alloc_ - !alloc_,                           \
464                         offsetof (VEC(TDEF),vec), sizeof (TDEF));         \
465 }                                                                         \
466                                                                           \
467 static inline void *VEC_OP (TDEF,embedded_alloc)                          \
468      (size_t offset_, size_t alloc_)                                      \
469 {                                                                         \
470   return vec_embedded_alloc (offset_, offsetof (VEC(TDEF),vec),           \
471                              sizeof (TDEF), alloc_);                      \
472 }                                                                         \
473                                                                           \
474 static inline void VEC_OP (TDEF,reserve)                                  \
475      (VEC (TDEF) **vec_, size_t alloc_)                                   \
476 {                                                                         \
477   *vec_ = vec_o_reserve (*vec_, alloc_,                                   \
478                          offsetof (VEC(TDEF),vec), sizeof (TDEF));        \
479 }                                                                         \
480                                                                           \
481 static inline TDEF *VEC_OP (TDEF,quick_push)                              \
482      (VEC (TDEF) *vec_, const TDEF *obj_)                                 \
483 {                                                                         \
484   TDEF *slot_;                                                            \
485                                                                           \
486   VEC_ASSERT (vec_->num < vec_->alloc, "push", TDEF);                     \
487   slot_ = &vec_->vec[vec_->num++];                                        \
488   if (obj_)                                                               \
489     *slot_ = *obj_;                                                       \
490                                                                           \
491   return slot_;                                                           \
492 }                                                                         \
493                                                                           \
494 static inline TDEF *VEC_OP (TDEF,safe_push)                               \
495      (VEC (TDEF) **vec_, const TDEF *obj_)                                \
496 {                                                                         \
497   if (!*vec_ || (*vec_)->num == (*vec_)->alloc)                           \
498     VEC_OP (TDEF,reserve) (vec_, ~(size_t)0);                             \
499                                                                           \
500   return VEC_OP (TDEF,quick_push) (*vec_, obj_);                          \
501 }                                                                         \
502                                                                           \
503 static inline void VEC_OP (TDEF,pop)                                      \
504      (VEC (TDEF) *vec_)                                                   \
505 {                                                                         \
506   VEC_ASSERT (vec_->num, "pop", TDEF);                                    \
507   vec_->vec[--vec_->num];                                                 \
508 }                                                                         \
509                                                                           \
510 static inline TDEF *VEC_OP (TDEF,replace)                                 \
511      (VEC (TDEF) *vec_, size_t ix_, const TDEF *obj_)                     \
512 {                                                                         \
513   TDEF *slot_;                                                            \
514                                                                           \
515   VEC_ASSERT (ix_ < vec_->num, "replace", TDEF);                          \
516   slot_ = &vec_->vec[ix_];                                                \
517   if (obj_)                                                               \
518     *slot_ = *obj_;                                                       \
519                                                                           \
520   return slot_;                                                           \
521 }                                                                         \
522                                                                           \
523 static inline TDEF *VEC_OP (TDEF,quick_insert)                            \
524      (VEC (TDEF) *vec_, size_t ix_, const TDEF *obj_)                     \
525 {                                                                         \
526   TDEF *slot_;                                                            \
527                                                                           \
528   VEC_ASSERT (vec_->num < vec_->alloc, "insert", TDEF);                   \
529   VEC_ASSERT (ix_ <= vec_->num, "insert", TDEF);                          \
530   slot_ = &vec_->vec[ix_];                                                \
531   memmove (slot_ + 1, slot_, vec_->num++ - ix_);                          \
532   if (obj_)                                                               \
533     *slot_ = *obj_;                                                       \
534                                                                           \
535   return slot_;                                                           \
536 }                                                                         \
537                                                                           \
538 static inline TDEF *VEC_OP (TDEF,safe_insert)                             \
539      (VEC (TDEF) **vec_, size_t ix_, const TDEF *obj_)                    \
540 {                                                                         \
541   if (!*vec_ || (*vec_)->num == (*vec_)->alloc)                           \
542     VEC_OP (TDEF,reserve) (vec_, ~(size_t)0);                             \
543                                                                           \
544   return VEC_OP (TDEF,quick_insert) (*vec_, ix_, obj_);                   \
545 }                                                                         \
546                                                                           \
547 static inline void VEC_OP (TDEF,ordered_remove)                           \
548      (VEC (TDEF) *vec_, size_t ix_)                                       \
549 {                                                                         \
550   TDEF *slot_;                                                            \
551                                                                           \
552   VEC_ASSERT (ix_ < vec_->num, "remove", TDEF);                           \
553   slot_ = &vec_->vec[ix_];                                                \
554   memmove (slot_, slot_ + 1, --vec_->num - ix_);                          \
555 }                                                                         \
556                                                                           \
557 static inline void VEC_OP (TDEF,unordered_remove)                         \
558      (VEC (TDEF) *vec_, size_t ix_)                                       \
559 {                                                                         \
560   VEC_ASSERT (ix_ < vec_->num, "remove", TDEF);                           \
561   vec_->vec[ix_] = vec_->vec[--vec_->num];                                \
562 }                                                                         \
563                                                                           \
564 struct vec_swallow_trailing_semi
565 #endif
566
567 #endif /* GCC_VEC_H */