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 = 0);
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 (const T
& VEC_CHECK_DECL
);
182 T
&pop (ALONE_VEC_CHECK_DECL
);
183 void truncate (unsigned VEC_CHECK_DECL
);
184 void replace (unsigned, const T
& VEC_CHECK_DECL
);
185 void quick_insert (unsigned, const T
& VEC_CHECK_DECL
);
186 void ordered_remove (unsigned VEC_CHECK_DECL
);
187 void unordered_remove (unsigned VEC_CHECK_DECL
);
188 void block_remove (unsigned, unsigned VEC_CHECK_DECL
);
189 unsigned lower_bound (T
, bool (*)(const T
&, const T
&)) const;
191 /* Class-static member functions. Some of these will become member
192 functions of a future handler class wrapping vec_t. */
193 static size_t embedded_size (int);
195 template<enum vec_allocation_t A
>
196 static vec_t
<T
> *alloc (int MEM_STAT_DECL
);
198 static vec_t
<T
> *alloc (int, vec_t
<T
> *);
200 template<enum vec_allocation_t A
>
201 static void free (vec_t
<T
> **);
203 template<enum vec_allocation_t A
>
204 static vec_t
<T
> *reserve_exact (vec_t
<T
> *, int MEM_STAT_DECL
);
206 template<enum vec_allocation_t A
>
207 static bool reserve_exact (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
209 template<enum vec_allocation_t A
>
210 static vec_t
<T
> *reserve (vec_t
<T
> *, int MEM_STAT_DECL
);
212 template<enum vec_allocation_t A
>
213 static bool reserve (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
215 template<enum vec_allocation_t A
>
216 static void safe_splice (vec_t
<T
> **, vec_t
<T
> * VEC_CHECK_DECL
219 template<enum vec_allocation_t A
>
220 static T
*safe_push (vec_t
<T
> **, const T
& VEC_CHECK_DECL MEM_STAT_DECL
);
222 template<enum vec_allocation_t A
>
223 static void safe_grow (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
225 template<enum vec_allocation_t A
>
226 static void safe_grow_cleared (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
228 template<enum vec_allocation_t A
>
229 static void safe_insert (vec_t
<T
> **, unsigned, const T
& VEC_CHECK_DECL
232 static bool iterate (const vec_t
<T
> *, unsigned, T
*);
233 static bool iterate (const vec_t
<T
> *, unsigned, T
**);
240 /* Garbage collection support for vec_t. */
244 gt_ggc_mx (vec_t
<T
> *v
)
246 extern void gt_ggc_mx (T
&);
247 for (unsigned i
= 0; i
< v
->length (); i
++)
252 /* PCH support for vec_t. */
256 gt_pch_nx (vec_t
<T
> *v
)
258 extern void gt_pch_nx (T
&);
259 for (unsigned i
= 0; i
< v
->length (); i
++)
265 gt_pch_nx (vec_t
<T
*> *v
, gt_pointer_operator op
, void *cookie
)
267 for (unsigned i
= 0; i
< v
->length (); i
++)
268 op (&((*v
)[i
]), cookie
);
273 gt_pch_nx (vec_t
<T
> *v
, gt_pointer_operator op
, void *cookie
)
275 extern void gt_pch_nx (T
*, gt_pointer_operator
, void *);
276 for (unsigned i
= 0; i
< v
->length (); i
++)
277 gt_pch_nx (&((*v
)[i
]), op
, cookie
);
281 /* FIXME. Remove these definitions and update all calling sites after
282 the handler class for vec_t is implemented. */
284 /* Vector of integer-like object. */
285 #define DEF_VEC_I(T) struct vec_swallow_trailing_semi
286 #define DEF_VEC_ALLOC_I(T,A) struct vec_swallow_trailing_semi
288 /* Vector of pointer to object. */
289 #define DEF_VEC_P(T) struct vec_swallow_trailing_semi
290 #define DEF_VEC_ALLOC_P(T,A) struct vec_swallow_trailing_semi
292 /* Vector of object. */
293 #define DEF_VEC_O(T) struct vec_swallow_trailing_semi
294 #define DEF_VEC_ALLOC_O(T,A) struct vec_swallow_trailing_semi
296 /* Vectors on the stack. */
297 #define DEF_VEC_ALLOC_P_STACK(T) struct vec_swallow_trailing_semi
298 #define DEF_VEC_ALLOC_O_STACK(T) struct vec_swallow_trailing_semi
299 #define DEF_VEC_ALLOC_I_STACK(T) struct vec_swallow_trailing_semi
301 /* Vectors of atomic types. Atomic types do not need to have its
302 elements marked for GC and PCH. To avoid unnecessary traversals,
303 we provide template instantiations for the GC/PCH functions that
304 do not traverse the vector.
306 FIXME cxx-conversion - Once vec_t users are converted this can
307 be provided in some other way (e.g., adding an additional template
308 parameter to the vec_t class). */
309 #define DEF_VEC_A(TYPE) \
310 template<typename T> \
312 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
316 template<typename T> \
318 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
322 template<typename T> \
324 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED, \
325 gt_pointer_operator op ATTRIBUTE_UNUSED, \
326 void *cookie ATTRIBUTE_UNUSED) \
329 struct vec_swallow_trailing_semi
331 #define DEF_VEC_ALLOC_A(T,A) struct vec_swallow_trailing_semi
333 /* Support functions for stack vectors. */
334 extern void *vec_stack_p_reserve_exact_1 (int, void *);
335 extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL
);
336 extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
338 extern void vec_stack_free (void *);
340 extern void dump_vec_loc_statistics (void);
341 extern void ggc_free (void *);
342 extern void vec_heap_free (void *);
345 /* API compatibility macros (to be removed). */
346 #define VEC_length(T,V) \
347 ((V) ? (V)->length () : 0)
349 #define VEC_empty(T,V) \
350 ((V) ? (V)->empty () : true)
352 #define VEC_address(T,V) \
355 /* FIXME. For now, we need to continue expanding VEC_address into a
356 function call. Otherwise, the warning machinery for -Wnonnull gets
357 confused thinking that VEC_address may return null in calls to
358 memcpy and qsort. This will disappear once vec_address becomes
359 a member function for a handler class wrapping vec_t. */
363 vec_address (vec_t
<T
> *vec
)
365 return vec
? vec
->address() : NULL
;
368 #define VEC_last(T,V) \
369 ((V)->last (ALONE_VEC_CHECK_INFO))
371 #define VEC_index(T,V,I) \
374 #define VEC_iterate(T,V,I,P) \
375 (vec_t<T>::iterate(V, I, &(P)))
377 #define VEC_embedded_size(T,N) \
378 (vec_t<T>::embedded_size (N))
380 #define VEC_embedded_init(T,V,N) \
381 ((V)->embedded_init (N))
383 #define VEC_free(T,A,V) \
384 (vec_t<T>::free<A> (&(V)))
386 #define VEC_copy(T,A,V) \
387 ((V)->copy<A> (ALONE_MEM_STAT_INFO))
389 #define VEC_space(T,V,R) \
390 ((V) ? (V)->space (R VEC_CHECK_INFO) : (R) == 0)
392 #define VEC_reserve(T,A,V,R) \
393 (vec_t<T>::reserve<A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO))
395 #define VEC_reserve_exact(T,A,V,R) \
396 (vec_t<T>::reserve_exact<A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO))
398 #define VEC_splice(T,DST,SRC) \
399 (DST)->splice (SRC VEC_CHECK_INFO)
401 #define VEC_safe_splice(T,A,DST,SRC) \
402 vec_t<T>::safe_splice<A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)
404 #define VEC_quick_push(T,V,O) \
405 ((V)->quick_push (O VEC_CHECK_INFO))
407 #define VEC_safe_push(T,A,V,O) \
408 (vec_t<T>::safe_push<A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO))
410 #define VEC_pop(T,V) \
411 ((V)->pop (ALONE_VEC_CHECK_INFO))
413 #define VEC_truncate(T,V,I) \
415 ? (V)->truncate ((unsigned)(I) VEC_CHECK_INFO) \
416 : gcc_assert ((I) == 0))
418 #define VEC_safe_grow(T,A,V,I) \
419 (vec_t<T>::safe_grow<A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO))
421 #define VEC_safe_grow_cleared(T,A,V,I) \
422 (vec_t<T>::safe_grow_cleared<A> (&(V), (int)(I) \
423 VEC_CHECK_INFO MEM_STAT_INFO))
425 #define VEC_replace(T,V,I,O) \
426 ((V)->replace ((unsigned)(I), O VEC_CHECK_INFO))
428 #define VEC_quick_insert(T,V,I,O) \
429 ((V)->quick_insert (I,O VEC_CHECK_INFO))
431 #define VEC_safe_insert(T,A,V,I,O) \
432 (vec_t<T>::safe_insert<A> (&(V), I, O VEC_CHECK_INFO MEM_STAT_INFO))
434 #define VEC_ordered_remove(T,V,I) \
435 ((V)->ordered_remove (I VEC_CHECK_INFO))
437 #define VEC_unordered_remove(T,V,I) \
438 ((V)->unordered_remove (I VEC_CHECK_INFO))
440 #define VEC_block_remove(T,V,I,L) \
441 ((V)->block_remove (I, L VEC_CHECK_INFO))
443 #define VEC_lower_bound(T,V,O,LT) \
444 ((V)->lower_bound (O, LT))
447 /* Return the number of active elements in this vector. */
451 vec_t
<T
>::length (void) const
457 /* Return true if this vector has no active elements. */
461 vec_t
<T
>::empty (void) const
463 return length () == 0;
467 /* Return the address of the array of elements. If you need to
468 directly manipulate the array (for instance, you want to feed it
469 to qsort), use this accessor. */
473 vec_t
<T
>::address (void)
479 /* Get the final element of the vector, which must not be empty. */
483 vec_t
<T
>::last (ALONE_VEC_CHECK_DECL
)
485 VEC_ASSERT (prefix_
.num_
, "last", T
, base
);
486 return (*this)[prefix_
.num_
- 1];
490 /* Index into vector. Return the IX'th element. IX must be in the
491 domain of the vector. */
495 vec_t
<T
>::operator[] (unsigned ix
) const
497 gcc_assert (ix
< prefix_
.num_
);
503 vec_t
<T
>::operator[] (unsigned ix
)
505 gcc_assert (ix
< prefix_
.num_
);
510 /* Return iteration condition and update PTR to point to the IX'th
511 element of VEC. Use this to iterate over the elements of a vector
514 for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
517 FIXME. This is a static member function because if VEC is NULL,
518 PTR should be initialized to NULL. This will become a regular
519 member function of the handler class. */
523 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
*ptr
)
525 if (vec
&& ix
< vec
->prefix_
.num_
)
527 *ptr
= vec
->vec_
[ix
];
538 /* Return iteration condition and update *PTR to point to the
539 IX'th element of VEC. Use this to iterate over the elements of a
542 for (ix = 0; v->iterate(ix, &ptr); ix++)
545 This variant is for vectors of objects. FIXME, to be removed
546 once the distinction between vec_t<T> and vec_t<T *> disappears. */
550 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
**ptr
)
552 if (vec
&& ix
< vec
->prefix_
.num_
)
554 *ptr
= CONST_CAST (T
*, &vec
->vec_
[ix
]);
565 /* Convenience macro for forward iteration. */
567 #define FOR_EACH_VEC_ELT(T, V, I, P) \
568 for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))
570 /* Likewise, but start from FROM rather than 0. */
572 #define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM) \
573 for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))
575 /* Convenience macro for reverse iteration. */
577 #define FOR_EACH_VEC_ELT_REVERSE(T, V, I, P) \
578 for (I = VEC_length (T, (V)) - 1; \
579 VEC_iterate (T, (V), (I), (P)); \
583 /* Return the number of bytes needed to embed an instance of vec_t inside
584 another data structure.
586 Use these methods to determine the required size and initialization
587 of a vector V of type T embedded within another structure (as the
590 size_t vec_t<T>::embedded_size<T> (int reserve);
591 void v->embedded_init(int reserve, int active);
593 These allow the caller to perform the memory allocation. */
597 vec_t
<T
>::embedded_size (int nelems
)
599 return offsetof (vec_t
<T
>, vec_
) + nelems
* sizeof (T
);
603 /* Initialize the vector to contain room for NELEMS elements and
604 ACTIVE active elements. */
608 vec_t
<T
>::embedded_init (int nelems
, int active
)
610 prefix_
.num_
= active
;
611 prefix_
.alloc_
= nelems
;
615 /* Allocate a new vector with space for RESERVE objects. If RESERVE
616 is zero, NO vector is created.
618 Note that this allocator must always be a macro:
620 We support a vector which starts out with space on the stack and
621 switches to heap space when forced to reallocate. This works a
622 little differently. In the case of stack vectors, vec_alloc will
623 expand to a call to vec_alloc_1 that calls XALLOCAVAR to request the
624 initial allocation. This uses alloca to get the initial space.
625 Since alloca can not be usefully called in an inline function,
626 vec_alloc must always be a macro.
628 Important limitations of stack vectors:
630 - Only the initial allocation will be made using alloca, so pass a
631 reasonable estimate that doesn't use too much stack space; don't
634 - Don't return a stack-allocated vector from the function which
637 #define VEC_alloc(T,A,N) \
639 ? vec_t<T>::alloc (N, XALLOCAVAR (vec_t<T>, vec_t<T>::embedded_size (N)))\
640 : vec_t<T>::alloc<A> (N MEM_STAT_INFO))
643 template<enum vec_allocation_t A
>
645 vec_t
<T
>::alloc (int nelems MEM_STAT_DECL
)
647 return reserve_exact
<A
> ((vec_t
<T
> *) NULL
, nelems PASS_MEM_STAT
);
652 vec_t
<T
>::alloc (int nelems
, vec_t
<T
> *space
)
654 return static_cast <vec_t
<T
> *> (vec_stack_p_reserve_exact_1 (nelems
, space
));
658 /* Free vector *V and set it to NULL. */
661 template<enum vec_allocation_t A
>
663 vec_t
<T
>::free (vec_t
<T
> **v
)
678 /* Return a copy of this vector. The new and old vectors need not be
679 allocated by the same mechanism. */
682 template<enum vec_allocation_t A
>
684 vec_t
<T
>::copy (ALONE_MEM_STAT_DECL
)
686 unsigned len
= VEC_length (T
, this);
687 vec_t
<T
> *new_vec
= NULL
;
691 new_vec
= reserve_exact
<A
> (static_cast<vec_t
<T
> *> (NULL
),
693 new_vec
->embedded_init (len
, len
);
694 memcpy (new_vec
->address (), vec_
, sizeof (T
) * len
);
701 /* If this vector has space for RESERVE additional entries, return
702 true. You usually only need to use this if you are doing your
703 own vector reallocation, for instance on an embedded vector. This
704 returns true in exactly the same circumstances that vec_reserve
709 vec_t
<T
>::space (int nelems VEC_CHECK_DECL
)
711 VEC_ASSERT (nelems
>= 0, "space", T
, base
);
712 return prefix_
.alloc_
- prefix_
.num_
>= static_cast <unsigned> (nelems
);
716 /* Ensure that the vector **VEC has at least RESERVE slots available. This
717 will create additional headroom. Note this can cause **VEC to
718 be reallocated. Returns true iff reallocation actually occurred. */
721 template<enum vec_allocation_t A
>
723 vec_t
<T
>::reserve (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL MEM_STAT_DECL
)
725 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
728 *vec
= reserve
<A
> (*vec
, nelems PASS_MEM_STAT
);
734 /* Ensure that **VEC has at least NELEMS slots available. This will not
735 create additional headroom. Note this can cause VEC to be
736 reallocated. Returns true iff reallocation actually occurred. */
739 template<enum vec_allocation_t A
>
741 vec_t
<T
>::reserve_exact (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL
744 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
747 *vec
= reserve_exact
<A
> (*vec
, nelems PASS_MEM_STAT
);
753 /* Copy the elements from SRC to the end of this vector as if by memcpy.
754 SRC and this vector need not be allocated with the same mechanism,
755 although they most often will be. This vector is assumed to have
756 sufficient headroom available. */
760 vec_t
<T
>::splice (vec_t
<T
> *src VEC_CHECK_DECL
)
764 unsigned len
= VEC_length (T
, src
);
765 VEC_ASSERT (VEC_length (T
, this) + len
<= prefix_
.alloc_
, "splice", T
,
767 memcpy (address () + VEC_length (T
, this),
775 /* Copy the elements in SRC to the end of DST as if by memcpy. DST and
776 SRC need not be allocated with the same mechanism, although they most
777 often will be. DST need not have sufficient headroom and will be
778 reallocated if needed. */
781 template<enum vec_allocation_t A
>
783 vec_t
<T
>::safe_splice (vec_t
<T
> **dst
, vec_t
<T
> *src VEC_CHECK_DECL
788 reserve_exact
<A
> (dst
, VEC_length (T
, src
) VEC_CHECK_PASS MEM_STAT_INFO
);
789 (*dst
)->splice (src VEC_CHECK_PASS
);
794 /* Push OBJ (a new element) onto the end of the vector. There must be
795 sufficient space in the vector. Return a pointer to the slot
796 where OBJ was inserted. */
801 vec_t
<T
>::quick_push (const T
&obj VEC_CHECK_DECL
)
803 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "push", T
, base
);
804 T
*slot
= &vec_
[prefix_
.num_
++];
810 /* Push a new element OBJ onto the end of VEC. Reallocates VEC, if
811 needed. Return a pointer to the slot where OBJ was inserted. */
814 template<enum vec_allocation_t A
>
816 vec_t
<T
>::safe_push (vec_t
<T
> **vec
, const T
&obj VEC_CHECK_DECL MEM_STAT_DECL
)
818 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
819 return (*vec
)->quick_push (obj VEC_CHECK_PASS
);
823 /* Pop and return the last element off the end of the vector. */
828 vec_t
<T
>::pop (ALONE_VEC_CHECK_DECL
)
830 VEC_ASSERT (prefix_
.num_
, "pop", T
, base
);
831 return vec_
[--prefix_
.num_
];
835 /* Set the length of the vector to LEN. The new length must be less
836 than or equal to the current length. This is an O(1) operation. */
840 vec_t
<T
>::truncate (unsigned size VEC_CHECK_DECL
)
842 VEC_ASSERT (prefix_
.num_
>= size
, "truncate", T
, base
);
847 /* Grow the vector VEC to a specific length. The LEN must be as
848 long or longer than the current length. The new elements are
852 template<enum vec_allocation_t A
>
854 vec_t
<T
>::safe_grow (vec_t
<T
> **vec
, int size VEC_CHECK_DECL MEM_STAT_DECL
)
856 VEC_ASSERT (size
>= 0 && VEC_length (T
, *vec
) <= (unsigned)size
,
858 reserve_exact
<A
> (vec
, size
- (int)VEC_length (T
, *vec
)
859 VEC_CHECK_PASS PASS_MEM_STAT
);
860 (*vec
)->prefix_
.num_
= size
;
864 /* Grow the vector *VEC to a specific length. The LEN must be as
865 long or longer than the current length. The new elements are
866 initialized to zero. */
869 template<enum vec_allocation_t A
>
871 vec_t
<T
>::safe_grow_cleared (vec_t
<T
> **vec
, int size VEC_CHECK_DECL
874 int oldsize
= VEC_length (T
, *vec
);
875 safe_grow
<A
> (vec
, size VEC_CHECK_PASS PASS_MEM_STAT
);
876 memset (&((*vec
)->address ()[oldsize
]), 0, sizeof (T
) * (size
- oldsize
));
880 /* Replace the IXth element of this vector with a new value, VAL. */
884 vec_t
<T
>::replace (unsigned ix
, const T
&obj VEC_CHECK_DECL
)
886 VEC_ASSERT (ix
< prefix_
.num_
, "replace", T
, base
);
891 /* Insert an element, OBJ, at the IXth position of VEC. There must be
896 vec_t
<T
>::quick_insert (unsigned ix
, const T
&obj VEC_CHECK_DECL
)
898 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "insert", T
, base
);
899 VEC_ASSERT (ix
<= prefix_
.num_
, "insert", T
, base
);
901 memmove (slot
+ 1, slot
, (prefix_
.num_
++ - ix
) * sizeof (T
));
906 /* Insert an element, OBJ, at the IXth position of VEC. Reallocate
907 VEC, if necessary. */
910 template<enum vec_allocation_t A
>
912 vec_t
<T
>::safe_insert (vec_t
<T
> **vec
, unsigned ix
, const T
&obj VEC_CHECK_DECL
915 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
916 (*vec
)->quick_insert (ix
, obj VEC_CHECK_PASS
);
920 /* Remove an element from the IXth position of this vector. Ordering of
921 remaining elements is preserved. This is an O(N) operation due to
926 vec_t
<T
>::ordered_remove (unsigned ix VEC_CHECK_DECL
)
928 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
930 memmove (slot
, slot
+ 1, (--prefix_
.num_
- ix
) * sizeof (T
));
934 /* Remove an element from the IXth position of VEC. Ordering of
935 remaining elements is destroyed. This is an O(1) operation. */
939 vec_t
<T
>::unordered_remove (unsigned ix VEC_CHECK_DECL
)
941 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
942 vec_
[ix
] = vec_
[--prefix_
.num_
];
946 /* Remove LEN elements starting at the IXth. Ordering is retained.
947 This is an O(N) operation due to memmove. */
951 vec_t
<T
>::block_remove (unsigned ix
, unsigned len VEC_CHECK_DECL
)
953 VEC_ASSERT (ix
+ len
<= prefix_
.num_
, "block_remove", T
, base
);
956 memmove (slot
, slot
+ len
, (prefix_
.num_
- ix
) * sizeof (T
));
959 /* Sort the contents of V with qsort. Use CMP as the comparison function. */
960 #define VEC_qsort(T,V,CMP) \
961 qsort (VEC_address (T, V), VEC_length (T, V), sizeof (T), CMP)
964 /* Find and return the first position in which OBJ could be inserted
965 without changing the ordering of this vector. LESSTHAN is a
966 function that returns true if the first argument is strictly less
971 vec_t
<T
>::lower_bound (T obj
, bool (*lessthan
)(const T
&, const T
&)) const
973 unsigned int len
= VEC_length (T
, this);
974 unsigned int half
, middle
;
975 unsigned int first
= 0;
981 T middle_elem
= (*this)[middle
];
982 if (lessthan (middle_elem
, obj
))
986 len
= len
- half
- 1;
995 void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
996 void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
998 /* Ensure there are at least RESERVE free slots in VEC_, growing
999 exponentially. If RESERVE < 0 grow exactly, else grow
1000 exponentially. As a special case, if VEC_ is NULL, and RESERVE is
1001 0, no vector will be created. */
1003 template<typename T
>
1004 template<enum vec_allocation_t A
>
1006 vec_t
<T
>::reserve (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
1009 size_t off
= offsetof (vec_t
<T
>, vec_
);
1010 size_t sz
= sizeof (T
);
1015 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1018 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1021 res
= vec_stack_o_reserve (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1025 return static_cast <vec_t
<T
> *> (res
);
1029 /* Ensure there are at least RESERVE free slots in VEC, growing
1030 exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
1031 a special case, if VEC is NULL, and RESERVE is 0, no vector will be
1034 template<typename T
>
1035 template<enum vec_allocation_t A
>
1037 vec_t
<T
>::reserve_exact (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
1040 size_t off
= sizeof (struct vec_prefix
);
1041 size_t sz
= sizeof (T
);
1043 gcc_assert (offsetof (vec_t
<T
>, vec_
) == sizeof (struct vec_prefix
));
1048 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1051 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1054 res
= vec_stack_o_reserve_exact (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1058 return static_cast <vec_t
<T
> *> (res
);
1061 #endif /* GCC_VEC_H */