1 /* Vector API for GNU compiler.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Nathan Sidwell <nathan@codesourcery.com>
5 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
26 #include "statistics.h" /* For MEM_STAT_DECL. */
28 /* Templated vector type and associated interfaces.
30 The interface functions are typesafe and use inline functions,
31 sometimes backed by out-of-line generic functions. The vectors are
32 designed to interoperate with the GTY machinery.
34 FIXME - Remove the following compatibility notes after a handler
35 class for vec_t is implemented.
37 To preserve compatibility with the existing API, some functions
38 that manipulate vector elements implement two overloads: one taking
39 a pointer to the element and others that take a pointer to a
40 pointer to the element.
42 This used to be implemented with three different families of macros
43 and structures: structure objects, scalar objects and of pointers.
44 Both the structure object and pointer variants passed pointers to
45 objects around -- in the former case the pointers were stored into
46 the vector and in the latter case the pointers were dereferenced and
47 the objects copied into the vector. The scalar object variant was
48 suitable for int-like objects, and the vector elements were returned
51 There are both 'index' and 'iterate' accessors. The index accessor
52 is implemented by operator[]. The iterator returns a boolean
53 iteration condition and updates the iteration variable passed by
54 reference. Because the iterator will be inlined, the address-of
55 can be optimized away.
57 The vectors are implemented using the trailing array idiom, thus
58 they are not resizeable without changing the address of the vector
59 object itself. This means you cannot have variables or fields of
60 vector type -- always use a pointer to a vector. The one exception
61 is the final field of a structure, which could be a vector type.
62 You will have to use the embedded_size & embedded_init calls to
63 create such objects, and they will probably not be resizeable (so
64 don't use the 'safe' allocation variants). The trailing array
65 idiom is used (rather than a pointer to an array of data), because,
66 if we allow NULL to also represent an empty vector, empty vectors
67 occupy minimal space in the structure containing them.
69 Each operation that increases the number of active elements is
70 available in 'quick' and 'safe' variants. The former presumes that
71 there is sufficient allocated space for the operation to succeed
72 (it dies if there is not). The latter will reallocate the
73 vector, if needed. Reallocation causes an exponential increase in
74 vector size. If you know you will be adding N elements, it would
75 be more efficient to use the reserve operation before adding the
76 elements with the 'quick' operation. This will ensure there are at
77 least as many elements as you ask for, it will exponentially
78 increase if there are too few spare slots. If you want reserve a
79 specific number of slots, but do not want the exponential increase
80 (for instance, you know this is the last allocation), use the
81 reserve_exact operation. You can also create a vector of a
82 specific size from the get go.
84 You should prefer the push and pop operations, as they append and
85 remove from the end of the vector. If you need to remove several
86 items in one go, use the truncate operation. The insert and remove
87 operations allow you to change elements in the middle of the
88 vector. There are two remove operations, one which preserves the
89 element ordering 'ordered_remove', and one which does not
90 'unordered_remove'. The latter function copies the end element
91 into the removed slot, rather than invoke a memmove operation. The
92 'lower_bound' function will determine where to place an item in the
93 array using insert that will maintain sorted order.
95 When a vector type is defined, first a non-memory managed version
96 is created. You can then define either or both garbage collected
97 and heap allocated versions. The allocation mechanism is specified
98 when the vector is allocated. This can occur via the VEC_alloc
99 call or one of the VEC_safe_* functions that add elements to a
100 vector. If the vector is NULL, it will be allocated using the
101 allocation strategy selected in the call. The valid allocations
102 are defined in enum vec_allocation_t.
104 If you need to directly manipulate a vector, then the 'address'
105 accessor will return the address of the start of the vector. Also
106 the 'space' predicate will tell you whether there is spare capacity
107 in the vector. You will not normally need to use these two functions.
109 Variables of vector type are of type vec_t<ETYPE> where ETYPE is
110 the type of the elements of the vector. Due to the way GTY works,
111 you must annotate any structures you wish to insert or reference
112 from a vector with a GTY(()) tag. You need to do this even if you
113 never use the GC allocated variants.
115 An example of their use would be,
118 vec_t<tree> *v; // A (pointer to) a vector of tree pointers.
123 if (VEC_length(tree,s->v)) { we have some contents }
124 VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
125 for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
126 { do something with elt }
131 #define ALONE_VEC_CHECK_INFO __FILE__, __LINE__, __FUNCTION__
132 #define VEC_CHECK_INFO , ALONE_VEC_CHECK_INFO
133 #define ALONE_VEC_CHECK_DECL const char *file_, unsigned line_, const char *function_
134 #define VEC_CHECK_DECL , ALONE_VEC_CHECK_DECL
135 #define ALONE_VEC_CHECK_PASS file_, line_, function_
136 #define VEC_CHECK_PASS , ALONE_VEC_CHECK_PASS
138 #define VEC_ASSERT(EXPR,OP,T,A) \
139 (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
141 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL
)
143 #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
145 #define ALONE_VEC_CHECK_INFO
146 #define VEC_CHECK_INFO
147 #define ALONE_VEC_CHECK_DECL void
148 #define VEC_CHECK_DECL
149 #define ALONE_VEC_CHECK_PASS
150 #define VEC_CHECK_PASS
151 #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
154 #define VEC(T,A) vec_t<T>
156 enum vec_allocation_t
{ heap
, gc
, stack
};
164 /* Vector type, user visible. */
168 unsigned length (void) const;
169 bool empty (void) const;
171 T
&last (ALONE_VEC_CHECK_DECL
);
172 const T
&operator[] (unsigned) const;
173 T
&operator[] (unsigned);
174 void embedded_init (int, int);
176 template<enum vec_allocation_t A
>
177 vec_t
<T
> *copy (ALONE_MEM_STAT_DECL
);
179 bool space (int VEC_CHECK_DECL
);
180 void splice (vec_t
<T
> * VEC_CHECK_DECL
);
181 T
&quick_push (T VEC_CHECK_DECL
);
182 T
*quick_push (const T
* VEC_CHECK_DECL
);
183 T
&pop (ALONE_VEC_CHECK_DECL
);
184 void truncate (unsigned VEC_CHECK_DECL
);
185 void replace (unsigned, T VEC_CHECK_DECL
);
186 void quick_insert (unsigned, T VEC_CHECK_DECL
);
187 void quick_insert (unsigned, const T
* VEC_CHECK_DECL
);
188 void ordered_remove (unsigned VEC_CHECK_DECL
);
189 void unordered_remove (unsigned VEC_CHECK_DECL
);
190 void block_remove (unsigned, unsigned VEC_CHECK_DECL
);
192 unsigned lower_bound (T
, bool (*)(T
, T
)) const;
193 unsigned lower_bound (const T
*, bool (*)(const T
*, const T
*)) const;
195 /* Class-static member functions. Some of these will become member
196 functions of a future handler class wrapping vec_t. */
197 static size_t embedded_size (int);
199 template<enum vec_allocation_t A
>
200 static vec_t
<T
> *alloc (int MEM_STAT_DECL
);
202 static vec_t
<T
> *alloc (int, vec_t
<T
> *);
204 template<enum vec_allocation_t A
>
205 static void free (vec_t
<T
> **);
207 template<enum vec_allocation_t A
>
208 static vec_t
<T
> *reserve_exact (vec_t
<T
> *, int MEM_STAT_DECL
);
210 template<enum vec_allocation_t A
>
211 static bool reserve_exact (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
213 template<enum vec_allocation_t A
>
214 static vec_t
<T
> *reserve (vec_t
<T
> *, int MEM_STAT_DECL
);
216 template<enum vec_allocation_t A
>
217 static bool reserve (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
219 template<enum vec_allocation_t A
>
220 static void safe_splice (vec_t
<T
> **, vec_t
<T
> * VEC_CHECK_DECL
223 template<enum vec_allocation_t A
>
224 static T
&safe_push (vec_t
<T
> **, T VEC_CHECK_DECL MEM_STAT_DECL
);
226 template<enum vec_allocation_t A
>
227 static T
*safe_push (vec_t
<T
> **, const T
* VEC_CHECK_DECL MEM_STAT_DECL
);
229 template<enum vec_allocation_t A
>
230 static void safe_grow (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
232 template<enum vec_allocation_t A
>
233 static void safe_grow_cleared (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
235 template<enum vec_allocation_t A
>
236 static void safe_insert (vec_t
<T
> **, unsigned, T
* VEC_CHECK_DECL
239 template<enum vec_allocation_t A
>
240 static void safe_insert (vec_t
<T
> **, unsigned, T obj VEC_CHECK_DECL
243 static bool iterate (const vec_t
<T
> *, unsigned, T
*);
244 static bool iterate (const vec_t
<T
> *, unsigned, T
**);
251 /* Garbage collection support for vec_t. */
255 gt_ggc_mx (vec_t
<T
> *v
)
257 extern void gt_ggc_mx (T
&);
258 for (unsigned i
= 0; i
< v
->length (); i
++)
263 /* PCH support for vec_t. */
267 gt_pch_nx (vec_t
<T
> *v
)
269 extern void gt_pch_nx (T
&);
270 for (unsigned i
= 0; i
< v
->length (); i
++)
276 gt_pch_nx (vec_t
<T
*> *v
, gt_pointer_operator op
, void *cookie
)
278 for (unsigned i
= 0; i
< v
->length (); i
++)
279 op (&((*v
)[i
]), cookie
);
284 gt_pch_nx (vec_t
<T
> *v
, gt_pointer_operator op
, void *cookie
)
286 extern void gt_pch_nx (T
*, gt_pointer_operator
, void *);
287 for (unsigned i
= 0; i
< v
->length (); i
++)
288 gt_pch_nx (&((*v
)[i
]), op
, cookie
);
292 /* FIXME. Remove these definitions and update all calling sites after
293 the handler class for vec_t is implemented. */
295 /* Vector of integer-like object. */
296 #define DEF_VEC_I(T) struct vec_swallow_trailing_semi
297 #define DEF_VEC_ALLOC_I(T,A) struct vec_swallow_trailing_semi
299 /* Vector of pointer to object. */
300 #define DEF_VEC_P(T) struct vec_swallow_trailing_semi
301 #define DEF_VEC_ALLOC_P(T,A) struct vec_swallow_trailing_semi
303 /* Vector of object. */
304 #define DEF_VEC_O(T) struct vec_swallow_trailing_semi
305 #define DEF_VEC_ALLOC_O(T,A) struct vec_swallow_trailing_semi
307 /* Vectors on the stack. */
308 #define DEF_VEC_ALLOC_P_STACK(T) struct vec_swallow_trailing_semi
309 #define DEF_VEC_ALLOC_O_STACK(T) struct vec_swallow_trailing_semi
310 #define DEF_VEC_ALLOC_I_STACK(T) struct vec_swallow_trailing_semi
312 /* Vectors of atomic types. Atomic types do not need to have its
313 elements marked for GC and PCH. To avoid unnecessary traversals,
314 we provide template instantiations for the GC/PCH functions that
315 do not traverse the vector.
317 FIXME cxx-conversion - Once vec_t users are converted this can
318 be provided in some other way (e.g., adding an additional template
319 parameter to the vec_t class). */
320 #define DEF_VEC_A(TYPE) \
321 template<typename T> \
323 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
327 template<typename T> \
329 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
333 template<typename T> \
335 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED, \
336 gt_pointer_operator op ATTRIBUTE_UNUSED, \
337 void *cookie ATTRIBUTE_UNUSED) \
340 struct vec_swallow_trailing_semi
342 #define DEF_VEC_ALLOC_A(T,A) struct vec_swallow_trailing_semi
344 /* Support functions for stack vectors. */
345 extern void *vec_stack_p_reserve_exact_1 (int, void *);
346 extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL
);
347 extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
349 extern void vec_stack_free (void *);
351 extern void dump_vec_loc_statistics (void);
352 extern void ggc_free (void *);
353 extern void vec_heap_free (void *);
356 /* API compatibility macros (to be removed). */
357 #define VEC_length(T,V) \
358 ((V) ? (V)->length () : 0)
360 #define VEC_empty(T,V) \
361 ((V) ? (V)->empty () : true)
363 #define VEC_address(T,V) \
366 /* FIXME. For now, we need to continue expanding VEC_address into a
367 function call. Otherwise, the warning machinery for -Wnonnull gets
368 confused thinking that VEC_address may return null in calls to
369 memcpy and qsort. This will disappear once vec_address becomes
370 a member function for a handler class wrapping vec_t. */
374 vec_address (vec_t
<T
> *vec
)
376 return vec
? vec
->address() : NULL
;
379 #define VEC_last(T,V) \
380 ((V)->last (ALONE_VEC_CHECK_INFO))
382 #define VEC_index(T,V,I) \
385 #define VEC_iterate(T,V,I,P) \
386 (vec_t<T>::iterate(V, I, &(P)))
388 #define VEC_embedded_size(T,N) \
389 (vec_t<T>::embedded_size (N))
391 #define VEC_embedded_init(T,V,N) \
392 ((V)->embedded_init (N))
394 #define VEC_free(T,A,V) \
395 (vec_t<T>::free<A> (&(V)))
397 #define VEC_copy(T,A,V) \
398 ((V)->copy<A> (ALONE_MEM_STAT_INFO))
400 #define VEC_space(T,V,R) \
401 ((V) ? (V)->space (R VEC_CHECK_INFO) : (R) == 0)
403 #define VEC_reserve(T,A,V,R) \
404 (vec_t<T>::reserve<A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO))
406 #define VEC_reserve_exact(T,A,V,R) \
407 (vec_t<T>::reserve_exact<A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO))
409 #define VEC_splice(T,DST,SRC) \
410 (DST)->splice (SRC VEC_CHECK_INFO)
412 #define VEC_safe_splice(T,A,DST,SRC) \
413 vec_t<T>::safe_splice<A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)
415 #define VEC_quick_push(T,V,O) \
416 ((V)->quick_push (O VEC_CHECK_INFO))
418 #define VEC_safe_push(T,A,V,O) \
419 (vec_t<T>::safe_push<A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO))
421 #define VEC_pop(T,V) \
422 ((V)->pop (ALONE_VEC_CHECK_INFO))
424 #define VEC_truncate(T,V,I) \
426 ? (V)->truncate ((unsigned)(I) VEC_CHECK_INFO) \
427 : gcc_assert ((I) == 0))
429 #define VEC_safe_grow(T,A,V,I) \
430 (vec_t<T>::safe_grow<A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO))
432 #define VEC_safe_grow_cleared(T,A,V,I) \
433 (vec_t<T>::safe_grow_cleared<A> (&(V), (int)(I) \
434 VEC_CHECK_INFO MEM_STAT_INFO))
436 #define VEC_replace(T,V,I,O) \
437 ((V)->replace ((unsigned)(I), O VEC_CHECK_INFO))
439 #define VEC_quick_insert(T,V,I,O) \
440 ((V)->quick_insert (I,O VEC_CHECK_INFO))
442 #define VEC_safe_insert(T,A,V,I,O) \
443 (vec_t<T>::safe_insert<A> (&(V), I, O VEC_CHECK_INFO MEM_STAT_INFO))
445 #define VEC_ordered_remove(T,V,I) \
446 ((V)->ordered_remove (I VEC_CHECK_INFO))
448 #define VEC_unordered_remove(T,V,I) \
449 ((V)->unordered_remove (I VEC_CHECK_INFO))
451 #define VEC_block_remove(T,V,I,L) \
452 ((V)->block_remove (I, L VEC_CHECK_INFO))
454 #define VEC_lower_bound(T,V,O,LT) \
455 ((V)->lower_bound (O, LT))
458 /* Return the number of active elements in this vector. */
462 vec_t
<T
>::length (void) const
468 /* Return true if this vector has no active elements. */
472 vec_t
<T
>::empty (void) const
474 return length () == 0;
478 /* Return the address of the array of elements. If you need to
479 directly manipulate the array (for instance, you want to feed it
480 to qsort), use this accessor. */
484 vec_t
<T
>::address (void)
490 /* Get the final element of the vector, which must not be empty. */
494 vec_t
<T
>::last (ALONE_VEC_CHECK_DECL
)
496 VEC_ASSERT (prefix_
.num_
, "last", T
, base
);
497 return (*this)[prefix_
.num_
- 1];
501 /* Index into vector. Return the IX'th element. IX must be in the
502 domain of the vector. */
506 vec_t
<T
>::operator[] (unsigned ix
) const
508 gcc_assert (ix
< prefix_
.num_
);
514 vec_t
<T
>::operator[] (unsigned ix
)
516 gcc_assert (ix
< prefix_
.num_
);
521 /* Return iteration condition and update PTR to point to the IX'th
522 element of VEC. Use this to iterate over the elements of a vector
525 for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
528 FIXME. This is a static member function because if VEC is NULL,
529 PTR should be initialized to NULL. This will become a regular
530 member function of the handler class. */
534 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
*ptr
)
536 if (vec
&& ix
< vec
->prefix_
.num_
)
538 *ptr
= vec
->vec_
[ix
];
549 /* Return iteration condition and update *PTR to point to the
550 IX'th element of VEC. Use this to iterate over the elements of a
553 for (ix = 0; v->iterate(ix, &ptr); ix++)
556 This variant is for vectors of objects. FIXME, to be removed
557 once the distinction between vec_t<T> and vec_t<T *> disappears. */
561 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
**ptr
)
563 if (vec
&& ix
< vec
->prefix_
.num_
)
565 *ptr
= CONST_CAST (T
*, &vec
->vec_
[ix
]);
576 /* Convenience macro for forward iteration. */
578 #define FOR_EACH_VEC_ELT(T, V, I, P) \
579 for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))
581 /* Likewise, but start from FROM rather than 0. */
583 #define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM) \
584 for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))
586 /* Convenience macro for reverse iteration. */
588 #define FOR_EACH_VEC_ELT_REVERSE(T, V, I, P) \
589 for (I = VEC_length (T, (V)) - 1; \
590 VEC_iterate (T, (V), (I), (P)); \
594 /* Return the number of bytes needed to embed an instance of vec_t inside
595 another data structure.
597 Use these methods to determine the required size and initialization
598 of a vector V of type T embedded within another structure (as the
601 size_t vec_t<T>::embedded_size<T> (int reserve);
602 void v->embedded_init(int reserve, int active = 0);
604 These allow the caller to perform the memory allocation. */
608 vec_t
<T
>::embedded_size (int nelems
)
610 return offsetof (vec_t
<T
>, vec_
) + nelems
* sizeof (T
);
614 /* Initialize the vector to contain room for NELEMS elements and
615 ACTIVE active elements. */
619 vec_t
<T
>::embedded_init (int nelems
, int active
= 0)
621 prefix_
.num_
= active
;
622 prefix_
.alloc_
= nelems
;
626 /* Allocate a new vector with space for RESERVE objects. If RESERVE
627 is zero, NO vector is created.
629 Note that this allocator must always be a macro:
631 We support a vector which starts out with space on the stack and
632 switches to heap space when forced to reallocate. This works a
633 little differently. In the case of stack vectors, vec_alloc will
634 expand to a call to vec_alloc_1 that calls XALLOCAVAR to request the
635 initial allocation. This uses alloca to get the initial space.
636 Since alloca can not be usefully called in an inline function,
637 vec_alloc must always be a macro.
639 Important limitations of stack vectors:
641 - Only the initial allocation will be made using alloca, so pass a
642 reasonable estimate that doesn't use too much stack space; don't
645 - Don't return a stack-allocated vector from the function which
648 #define VEC_alloc(T,A,N) \
650 ? vec_t<T>::alloc (N, XALLOCAVAR (vec_t<T>, vec_t<T>::embedded_size (N)))\
651 : vec_t<T>::alloc<A> (N MEM_STAT_INFO))
654 template<enum vec_allocation_t A
>
656 vec_t
<T
>::alloc (int nelems MEM_STAT_DECL
)
658 return reserve_exact
<A
> ((vec_t
<T
> *) NULL
, nelems PASS_MEM_STAT
);
663 vec_t
<T
>::alloc (int nelems
, vec_t
<T
> *space
)
665 return static_cast <vec_t
<T
> *> (vec_stack_p_reserve_exact_1 (nelems
, space
));
669 /* Free vector *V and set it to NULL. */
672 template<enum vec_allocation_t A
>
674 vec_t
<T
>::free (vec_t
<T
> **v
)
689 /* Return a copy of this vector. The new and old vectors need not be
690 allocated by the same mechanism. */
693 template<enum vec_allocation_t A
>
695 vec_t
<T
>::copy (ALONE_MEM_STAT_DECL
)
697 unsigned len
= VEC_length (T
, this);
698 vec_t
<T
> *new_vec
= NULL
;
702 new_vec
= reserve_exact
<A
> (static_cast<vec_t
<T
> *> (NULL
),
704 new_vec
->embedded_init (len
, len
);
705 memcpy (new_vec
->address (), vec_
, sizeof (T
) * len
);
712 /* If this vector has space for RESERVE additional entries, return
713 true. You usually only need to use this if you are doing your
714 own vector reallocation, for instance on an embedded vector. This
715 returns true in exactly the same circumstances that vec_reserve
720 vec_t
<T
>::space (int nelems VEC_CHECK_DECL
)
722 VEC_ASSERT (nelems
>= 0, "space", T
, base
);
723 return prefix_
.alloc_
- prefix_
.num_
>= static_cast <unsigned> (nelems
);
727 /* Ensure that the vector **VEC has at least RESERVE slots available. This
728 will create additional headroom. Note this can cause **VEC to
729 be reallocated. Returns true iff reallocation actually occurred. */
732 template<enum vec_allocation_t A
>
734 vec_t
<T
>::reserve (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL MEM_STAT_DECL
)
736 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
739 *vec
= reserve
<A
> (*vec
, nelems PASS_MEM_STAT
);
745 /* Ensure that **VEC has at least NELEMS slots available. This will not
746 create additional headroom. Note this can cause VEC to be
747 reallocated. Returns true iff reallocation actually occurred. */
750 template<enum vec_allocation_t A
>
752 vec_t
<T
>::reserve_exact (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL
755 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
758 *vec
= reserve_exact
<A
> (*vec
, nelems PASS_MEM_STAT
);
764 /* Copy the elements from SRC to the end of this vector as if by memcpy.
765 SRC and this vector need not be allocated with the same mechanism,
766 although they most often will be. This vector is assumed to have
767 sufficient headroom available. */
771 vec_t
<T
>::splice (vec_t
<T
> *src VEC_CHECK_DECL
)
775 unsigned len
= VEC_length (T
, src
);
776 VEC_ASSERT (VEC_length (T
, this) + len
<= prefix_
.alloc_
, "splice", T
,
778 memcpy (address () + VEC_length (T
, this),
786 /* Copy the elements in SRC to the end of DST as if by memcpy. DST and
787 SRC need not be allocated with the same mechanism, although they most
788 often will be. DST need not have sufficient headroom and will be
789 reallocated if needed. */
792 template<enum vec_allocation_t A
>
794 vec_t
<T
>::safe_splice (vec_t
<T
> **dst
, vec_t
<T
> *src VEC_CHECK_DECL
799 reserve_exact
<A
> (dst
, VEC_length (T
, src
) VEC_CHECK_PASS MEM_STAT_INFO
);
800 (*dst
)->splice (src VEC_CHECK_PASS
);
805 /* Push OBJ (a new element) onto the end, returns a reference to the slot
806 filled in. There must be sufficient space in the vector. */
810 vec_t
<T
>::quick_push (T obj VEC_CHECK_DECL
)
812 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "push", T
, base
);
813 vec_
[prefix_
.num_
] = obj
;
814 T
&val
= vec_
[prefix_
.num_
];
820 /* Push PTR (a new pointer to an element) onto the end, returns a
821 pointer to the slot filled in. The new value can be NULL, in which
822 case NO initialization is performed. There must be sufficient
823 space in the vector. */
827 vec_t
<T
>::quick_push (const T
*ptr VEC_CHECK_DECL
)
829 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "push", T
, base
);
830 T
*slot
= &vec_
[prefix_
.num_
++];
837 /* Push a new element OBJ onto the end of VEC. Returns a reference to
838 the slot filled in. Reallocates V, if needed. */
841 template<enum vec_allocation_t A
>
843 vec_t
<T
>::safe_push (vec_t
<T
> **vec
, T obj VEC_CHECK_DECL MEM_STAT_DECL
)
845 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
846 return (*vec
)->quick_push (obj VEC_CHECK_PASS
);
850 /* Push a pointer PTR to a new element onto the end of VEC. Returns a
851 pointer to the slot filled in. For object vectors, the new value
852 can be NULL, in which case NO initialization is performed.
853 Reallocates VEC, if needed. */
856 template<enum vec_allocation_t A
>
858 vec_t
<T
>::safe_push (vec_t
<T
> **vec
, const T
*ptr VEC_CHECK_DECL MEM_STAT_DECL
)
860 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
861 return (*vec
)->quick_push (ptr VEC_CHECK_PASS
);
865 /* Pop and return the last element off the end of the vector. */
870 vec_t
<T
>::pop (ALONE_VEC_CHECK_DECL
)
872 VEC_ASSERT (prefix_
.num_
, "pop", T
, base
);
873 return vec_
[--prefix_
.num_
];
877 /* Set the length of the vector to LEN. The new length must be less
878 than or equal to the current length. This is an O(1) operation. */
882 vec_t
<T
>::truncate (unsigned size VEC_CHECK_DECL
)
884 VEC_ASSERT (prefix_
.num_
>= size
, "truncate", T
, base
);
889 /* Grow the vector VEC to a specific length. The LEN must be as
890 long or longer than the current length. The new elements are
894 template<enum vec_allocation_t A
>
896 vec_t
<T
>::safe_grow (vec_t
<T
> **vec
, int size VEC_CHECK_DECL MEM_STAT_DECL
)
898 VEC_ASSERT (size
>= 0 && VEC_length (T
, *vec
) <= (unsigned)size
,
900 reserve_exact
<A
> (vec
, size
- (int)VEC_length (T
, *vec
)
901 VEC_CHECK_PASS PASS_MEM_STAT
);
902 (*vec
)->prefix_
.num_
= size
;
906 /* Grow the vector *VEC to a specific length. The LEN must be as
907 long or longer than the current length. The new elements are
908 initialized to zero. */
911 template<enum vec_allocation_t A
>
913 vec_t
<T
>::safe_grow_cleared (vec_t
<T
> **vec
, int size VEC_CHECK_DECL
916 int oldsize
= VEC_length (T
, *vec
);
917 safe_grow
<A
> (vec
, size VEC_CHECK_PASS PASS_MEM_STAT
);
918 memset (&((*vec
)->address ()[oldsize
]), 0, sizeof (T
) * (size
- oldsize
));
922 /* Replace the IXth element of this vector with a new value, VAL. */
926 vec_t
<T
>::replace (unsigned ix
, T obj VEC_CHECK_DECL
)
928 VEC_ASSERT (ix
< prefix_
.num_
, "replace", T
, base
);
933 /* Insert an element, OBJ, at the IXth position of VEC. There must be
938 vec_t
<T
>::quick_insert (unsigned ix
, T obj VEC_CHECK_DECL
)
940 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "insert", T
, base
);
941 VEC_ASSERT (ix
<= prefix_
.num_
, "insert", T
, base
);
943 memmove (slot
+ 1, slot
, (prefix_
.num_
++ - ix
) * sizeof (T
));
948 /* Insert an element, *PTR, at the IXth position of V. The new value
949 can be NULL, in which case no initialization of the inserted slot
950 takes place. There must be sufficient space. */
954 vec_t
<T
>::quick_insert (unsigned ix
, const T
*ptr VEC_CHECK_DECL
)
956 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "insert", T
, base
);
957 VEC_ASSERT (ix
<= prefix_
.num_
, "insert", T
, base
);
959 memmove (slot
+ 1, slot
, (prefix_
.num_
++ - ix
) * sizeof (T
));
965 /* Insert an element, VAL, at the IXth position of VEC. Reallocate
966 VEC, if necessary. */
969 template<enum vec_allocation_t A
>
971 vec_t
<T
>::safe_insert (vec_t
<T
> **vec
, unsigned ix
, T obj VEC_CHECK_DECL
974 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
975 (*vec
)->quick_insert (ix
, obj VEC_CHECK_PASS
);
979 /* Insert an element, *PTR, at the IXth position of VEC. Return a pointer
980 to the slot created. For vectors of object, the new value can be
981 NULL, in which case no initialization of the inserted slot takes
982 place. Reallocate V, if necessary. */
985 template<enum vec_allocation_t A
>
987 vec_t
<T
>::safe_insert (vec_t
<T
> **vec
, unsigned ix
, T
*ptr VEC_CHECK_DECL
990 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
991 (*vec
)->quick_insert (ix
, ptr VEC_CHECK_PASS
);
995 /* Remove an element from the IXth position of this vector. Ordering of
996 remaining elements is preserved. This is an O(N) operation due to
1001 vec_t
<T
>::ordered_remove (unsigned ix VEC_CHECK_DECL
)
1003 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
1004 T
*slot
= &vec_
[ix
];
1005 memmove (slot
, slot
+ 1, (--prefix_
.num_
- ix
) * sizeof (T
));
1009 /* Remove an element from the IXth position of VEC. Ordering of
1010 remaining elements is destroyed. This is an O(1) operation. */
1012 template<typename T
>
1014 vec_t
<T
>::unordered_remove (unsigned ix VEC_CHECK_DECL
)
1016 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
1017 vec_
[ix
] = vec_
[--prefix_
.num_
];
1021 /* Remove LEN elements starting at the IXth. Ordering is retained.
1022 This is an O(N) operation due to memmove. */
1024 template<typename T
>
1026 vec_t
<T
>::block_remove (unsigned ix
, unsigned len VEC_CHECK_DECL
)
1028 VEC_ASSERT (ix
+ len
<= prefix_
.num_
, "block_remove", T
, base
);
1029 T
*slot
= &vec_
[ix
];
1030 prefix_
.num_
-= len
;
1031 memmove (slot
, slot
+ len
, (prefix_
.num_
- ix
) * sizeof (T
));
1034 /* Sort the contents of V with qsort. Use CMP as the comparison function. */
1035 #define VEC_qsort(T,V,CMP) \
1036 qsort (VEC_address (T, V), VEC_length (T, V), sizeof (T), CMP)
1039 /* Find and return the first position in which OBJ could be inserted
1040 without changing the ordering of this vector. LESSTHAN is a
1041 function that returns true if the first argument is strictly less
1044 template<typename T
>
1046 vec_t
<T
>::lower_bound (T obj
, bool (*lessthan
)(T
, T
)) const
1048 unsigned int len
= VEC_length (T
, this);
1049 unsigned int half
, middle
;
1050 unsigned int first
= 0;
1056 T middle_elem
= (*this)[middle
];
1057 if (lessthan (middle_elem
, obj
))
1061 len
= len
- half
- 1;
1070 /* Find and return the first position in which *PTR could be inserted
1071 without changing the ordering of this vector. LESSTHAN is a
1072 function that returns true if the first argument is strictly less
1075 template<typename T
>
1077 vec_t
<T
>::lower_bound (const T
*ptr
,
1078 bool (*lessthan_
)(const T
*, const T
*)) const
1080 unsigned int len
= VEC_length (T
, this);
1081 unsigned int half
, middle
;
1082 unsigned int first
= 0;
1088 const T
*middle_elem
= &(*this)[middle
];
1089 if (lessthan (middle_elem
, ptr
))
1093 len
= len
- half
- 1;
1102 void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
1103 void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
1105 /* Ensure there are at least RESERVE free slots in VEC_, growing
1106 exponentially. If RESERVE < 0 grow exactly, else grow
1107 exponentially. As a special case, if VEC_ is NULL, and RESERVE is
1108 0, no vector will be created. */
1110 template<typename T
>
1111 template<enum vec_allocation_t A
>
1113 vec_t
<T
>::reserve (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
1116 size_t off
= offsetof (vec_t
<T
>, vec_
);
1117 size_t sz
= sizeof (T
);
1122 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1125 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1128 res
= vec_stack_o_reserve (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1132 return static_cast <vec_t
<T
> *> (res
);
1136 /* Ensure there are at least RESERVE free slots in VEC, growing
1137 exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
1138 a special case, if VEC is NULL, and RESERVE is 0, no vector will be
1141 template<typename T
>
1142 template<enum vec_allocation_t A
>
1144 vec_t
<T
>::reserve_exact (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
1147 size_t off
= sizeof (struct vec_prefix
);
1148 size_t sz
= sizeof (T
);
1150 gcc_assert (offsetof (vec_t
<T
>, vec_
) == sizeof (struct vec_prefix
));
1155 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1158 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1161 res
= vec_stack_o_reserve_exact (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1165 return static_cast <vec_t
<T
> *> (res
);
1168 #endif /* GCC_VEC_H */