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 There are both 'index' and 'iterate' accessors. The index accessor
35 is implemented by operator[]. The iterator returns a boolean
36 iteration condition and updates the iteration variable passed by
37 reference. Because the iterator will be inlined, the address-of
38 can be optimized away.
40 The vectors are implemented using the trailing array idiom, thus
41 they are not resizeable without changing the address of the vector
42 object itself. This means you cannot have variables or fields of
43 vector type -- always use a pointer to a vector. The one exception
44 is the final field of a structure, which could be a vector type.
45 You will have to use the embedded_size & embedded_init calls to
46 create such objects, and they will probably not be resizeable (so
47 don't use the 'safe' allocation variants). The trailing array
48 idiom is used (rather than a pointer to an array of data), because,
49 if we allow NULL to also represent an empty vector, empty vectors
50 occupy minimal space in the structure containing them.
52 Each operation that increases the number of active elements is
53 available in 'quick' and 'safe' variants. The former presumes that
54 there is sufficient allocated space for the operation to succeed
55 (it dies if there is not). The latter will reallocate the
56 vector, if needed. Reallocation causes an exponential increase in
57 vector size. If you know you will be adding N elements, it would
58 be more efficient to use the reserve operation before adding the
59 elements with the 'quick' operation. This will ensure there are at
60 least as many elements as you ask for, it will exponentially
61 increase if there are too few spare slots. If you want reserve a
62 specific number of slots, but do not want the exponential increase
63 (for instance, you know this is the last allocation), use the
64 reserve_exact operation. You can also create a vector of a
65 specific size from the get go.
67 You should prefer the push and pop operations, as they append and
68 remove from the end of the vector. If you need to remove several
69 items in one go, use the truncate operation. The insert and remove
70 operations allow you to change elements in the middle of the
71 vector. There are two remove operations, one which preserves the
72 element ordering 'ordered_remove', and one which does not
73 'unordered_remove'. The latter function copies the end element
74 into the removed slot, rather than invoke a memmove operation. The
75 'lower_bound' function will determine where to place an item in the
76 array using insert that will maintain sorted order.
78 When a vector type is defined, first a non-memory managed version
79 is created. You can then define either or both garbage collected
80 and heap allocated versions. The allocation mechanism is specified
81 when the vector is allocated. This can occur via the VEC_alloc
82 call or one of the VEC_safe_* functions that add elements to a
83 vector. If the vector is NULL, it will be allocated using the
84 allocation strategy selected in the call. The valid allocations
85 are defined in enum vec_allocation_t.
87 If you need to directly manipulate a vector, then the 'address'
88 accessor will return the address of the start of the vector. Also
89 the 'space' predicate will tell you whether there is spare capacity
90 in the vector. You will not normally need to use these two functions.
92 Variables of vector type are of type vec_t<ETYPE> where ETYPE is
93 the type of the elements of the vector. Due to the way GTY works,
94 you must annotate any structures you wish to insert or reference
95 from a vector with a GTY(()) tag. You need to do this even if you
96 never use the GC allocated variants.
98 An example of their use would be,
101 vec_t<tree> *v; // A (pointer to) a vector of tree pointers.
106 if (VEC_length(tree,s->v)) { we have some contents }
107 VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
108 for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
109 { do something with elt }
113 #define ALONE_VEC_CHECK_INFO __FILE__, __LINE__, __FUNCTION__
114 #define VEC_CHECK_INFO , ALONE_VEC_CHECK_INFO
115 #define ALONE_VEC_CHECK_DECL const char *file_, unsigned line_, const char *function_
116 #define VEC_CHECK_DECL , ALONE_VEC_CHECK_DECL
117 #define ALONE_VEC_CHECK_PASS file_, line_, function_
118 #define VEC_CHECK_PASS , ALONE_VEC_CHECK_PASS
120 #define VEC_ASSERT(EXPR,OP,T,A) \
121 (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
123 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL
)
125 #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
127 #define ALONE_VEC_CHECK_INFO
128 #define VEC_CHECK_INFO
129 #define ALONE_VEC_CHECK_DECL void
130 #define VEC_CHECK_DECL
131 #define ALONE_VEC_CHECK_PASS
132 #define VEC_CHECK_PASS
133 #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
136 #define VEC(T,A) vec_t<T>
138 enum vec_allocation_t
{ heap
, gc
, stack
};
146 /* Vector type, user visible. */
150 unsigned length (void) const;
151 bool empty (void) const;
153 T
&last (ALONE_VEC_CHECK_DECL
);
154 const T
&operator[] (unsigned) const;
155 T
&operator[] (unsigned);
156 void embedded_init (int, int = 0);
158 template<enum vec_allocation_t A
>
159 vec_t
<T
> *copy (ALONE_MEM_STAT_DECL
);
161 bool space (int VEC_CHECK_DECL
);
162 void splice (vec_t
<T
> * VEC_CHECK_DECL
);
163 T
*quick_push (const T
& VEC_CHECK_DECL
);
164 T
&pop (ALONE_VEC_CHECK_DECL
);
165 void truncate (unsigned VEC_CHECK_DECL
);
166 void replace (unsigned, const T
& VEC_CHECK_DECL
);
167 void quick_insert (unsigned, const T
& VEC_CHECK_DECL
);
168 void ordered_remove (unsigned VEC_CHECK_DECL
);
169 void unordered_remove (unsigned VEC_CHECK_DECL
);
170 void block_remove (unsigned, unsigned VEC_CHECK_DECL
);
171 unsigned lower_bound (T
, bool (*)(const T
&, const T
&)) const;
173 /* Class-static member functions. Some of these will become member
174 functions of a future handler class wrapping vec_t. */
175 static size_t embedded_size (int);
177 template<enum vec_allocation_t A
>
178 static vec_t
<T
> *alloc (int MEM_STAT_DECL
);
180 static vec_t
<T
> *alloc (int, vec_t
<T
> *);
182 template<enum vec_allocation_t A
>
183 static void free (vec_t
<T
> **);
185 template<enum vec_allocation_t A
>
186 static vec_t
<T
> *reserve_exact (vec_t
<T
> *, int MEM_STAT_DECL
);
188 template<enum vec_allocation_t A
>
189 static bool reserve_exact (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
191 template<enum vec_allocation_t A
>
192 static vec_t
<T
> *reserve (vec_t
<T
> *, int MEM_STAT_DECL
);
194 template<enum vec_allocation_t A
>
195 static bool reserve (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
197 template<enum vec_allocation_t A
>
198 static void safe_splice (vec_t
<T
> **, vec_t
<T
> * VEC_CHECK_DECL
201 template<enum vec_allocation_t A
>
202 static T
*safe_push (vec_t
<T
> **, const T
& VEC_CHECK_DECL MEM_STAT_DECL
);
204 template<enum vec_allocation_t A
>
205 static void safe_grow (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
207 template<enum vec_allocation_t A
>
208 static void safe_grow_cleared (vec_t
<T
> **, int VEC_CHECK_DECL MEM_STAT_DECL
);
210 template<enum vec_allocation_t A
>
211 static void safe_insert (vec_t
<T
> **, unsigned, const T
& VEC_CHECK_DECL
214 static bool iterate (const vec_t
<T
> *, unsigned, T
*);
215 static bool iterate (const vec_t
<T
> *, unsigned, T
**);
222 /* Garbage collection support for vec_t. */
226 gt_ggc_mx (vec_t
<T
> *v
)
228 extern void gt_ggc_mx (T
&);
229 for (unsigned i
= 0; i
< v
->length (); i
++)
234 /* PCH support for vec_t. */
238 gt_pch_nx (vec_t
<T
> *v
)
240 extern void gt_pch_nx (T
&);
241 for (unsigned i
= 0; i
< v
->length (); i
++)
247 gt_pch_nx (vec_t
<T
*> *v
, gt_pointer_operator op
, void *cookie
)
249 for (unsigned i
= 0; i
< v
->length (); i
++)
250 op (&((*v
)[i
]), cookie
);
255 gt_pch_nx (vec_t
<T
> *v
, gt_pointer_operator op
, void *cookie
)
257 extern void gt_pch_nx (T
*, gt_pointer_operator
, void *);
258 for (unsigned i
= 0; i
< v
->length (); i
++)
259 gt_pch_nx (&((*v
)[i
]), op
, cookie
);
263 /* FIXME. Remove these definitions and update all calling sites after
264 the handler class for vec_t is implemented. */
266 /* Vector of integer-like object. */
267 #define DEF_VEC_I(T) struct vec_swallow_trailing_semi
268 #define DEF_VEC_ALLOC_I(T,A) struct vec_swallow_trailing_semi
270 /* Vector of pointer to object. */
271 #define DEF_VEC_P(T) struct vec_swallow_trailing_semi
272 #define DEF_VEC_ALLOC_P(T,A) struct vec_swallow_trailing_semi
274 /* Vector of object. */
275 #define DEF_VEC_O(T) struct vec_swallow_trailing_semi
276 #define DEF_VEC_ALLOC_O(T,A) struct vec_swallow_trailing_semi
278 /* Vectors on the stack. */
279 #define DEF_VEC_ALLOC_P_STACK(T) struct vec_swallow_trailing_semi
280 #define DEF_VEC_ALLOC_O_STACK(T) struct vec_swallow_trailing_semi
281 #define DEF_VEC_ALLOC_I_STACK(T) struct vec_swallow_trailing_semi
283 /* Vectors of atomic types. Atomic types do not need to have its
284 elements marked for GC and PCH. To avoid unnecessary traversals,
285 we provide template instantiations for the GC/PCH functions that
286 do not traverse the vector.
288 FIXME cxx-conversion - Once vec_t users are converted this can
289 be provided in some other way (e.g., adding an additional template
290 parameter to the vec_t class). */
291 #define DEF_VEC_A(TYPE) \
292 template<typename T> \
294 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
298 template<typename T> \
300 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
304 template<typename T> \
306 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED, \
307 gt_pointer_operator op ATTRIBUTE_UNUSED, \
308 void *cookie ATTRIBUTE_UNUSED) \
311 struct vec_swallow_trailing_semi
313 #define DEF_VEC_ALLOC_A(T,A) struct vec_swallow_trailing_semi
315 /* Support functions for stack vectors. */
316 extern void *vec_stack_p_reserve_exact_1 (int, void *);
317 extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL
);
318 extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
320 extern void vec_stack_free (void *);
322 extern void dump_vec_loc_statistics (void);
323 extern void ggc_free (void *);
324 extern void vec_heap_free (void *);
327 /* API compatibility macros (to be removed). */
328 #define VEC_length(T,V) \
329 ((V) ? (V)->length () : 0)
331 #define VEC_empty(T,V) \
332 ((V) ? (V)->empty () : true)
334 #define VEC_address(T,V) \
337 /* FIXME. For now, we need to continue expanding VEC_address into a
338 function call. Otherwise, the warning machinery for -Wnonnull gets
339 confused thinking that VEC_address may return null in calls to
340 memcpy and qsort. This will disappear once vec_address becomes
341 a member function for a handler class wrapping vec_t. */
345 vec_address (vec_t
<T
> *vec
)
347 return vec
? vec
->address() : NULL
;
350 #define VEC_last(T,V) \
351 ((V)->last (ALONE_VEC_CHECK_INFO))
353 #define VEC_index(T,V,I) \
356 #define VEC_iterate(T,V,I,P) \
357 (vec_t<T>::iterate(V, I, &(P)))
359 #define VEC_embedded_size(T,N) \
360 (vec_t<T>::embedded_size (N))
362 #define VEC_embedded_init(T,V,N) \
363 ((V)->embedded_init (N))
365 #define VEC_free(T,A,V) \
366 (vec_t<T>::free<A> (&(V)))
368 #define VEC_copy(T,A,V) \
369 ((V)->copy<A> (ALONE_MEM_STAT_INFO))
371 #define VEC_space(T,V,R) \
372 ((V) ? (V)->space (R VEC_CHECK_INFO) : (R) == 0)
374 #define VEC_reserve(T,A,V,R) \
375 (vec_t<T>::reserve<A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO))
377 #define VEC_reserve_exact(T,A,V,R) \
378 (vec_t<T>::reserve_exact<A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO))
380 #define VEC_splice(T,DST,SRC) \
381 (DST)->splice (SRC VEC_CHECK_INFO)
383 #define VEC_safe_splice(T,A,DST,SRC) \
384 vec_t<T>::safe_splice<A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)
386 #define VEC_quick_push(T,V,O) \
387 ((V)->quick_push (O VEC_CHECK_INFO))
389 #define VEC_safe_push(T,A,V,O) \
390 (vec_t<T>::safe_push<A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO))
392 #define VEC_pop(T,V) \
393 ((V)->pop (ALONE_VEC_CHECK_INFO))
395 #define VEC_truncate(T,V,I) \
397 ? (V)->truncate ((unsigned)(I) VEC_CHECK_INFO) \
398 : gcc_assert ((I) == 0))
400 #define VEC_safe_grow(T,A,V,I) \
401 (vec_t<T>::safe_grow<A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO))
403 #define VEC_safe_grow_cleared(T,A,V,I) \
404 (vec_t<T>::safe_grow_cleared<A> (&(V), (int)(I) \
405 VEC_CHECK_INFO MEM_STAT_INFO))
407 #define VEC_replace(T,V,I,O) \
408 ((V)->replace ((unsigned)(I), O VEC_CHECK_INFO))
410 #define VEC_quick_insert(T,V,I,O) \
411 ((V)->quick_insert (I,O VEC_CHECK_INFO))
413 #define VEC_safe_insert(T,A,V,I,O) \
414 (vec_t<T>::safe_insert<A> (&(V), I, O VEC_CHECK_INFO MEM_STAT_INFO))
416 #define VEC_ordered_remove(T,V,I) \
417 ((V)->ordered_remove (I VEC_CHECK_INFO))
419 #define VEC_unordered_remove(T,V,I) \
420 ((V)->unordered_remove (I VEC_CHECK_INFO))
422 #define VEC_block_remove(T,V,I,L) \
423 ((V)->block_remove (I, L VEC_CHECK_INFO))
425 #define VEC_lower_bound(T,V,O,LT) \
426 ((V)->lower_bound (O, LT))
429 /* Return the number of active elements in this vector. */
433 vec_t
<T
>::length (void) const
439 /* Return true if this vector has no active elements. */
443 vec_t
<T
>::empty (void) const
445 return length () == 0;
449 /* Return the address of the array of elements. If you need to
450 directly manipulate the array (for instance, you want to feed it
451 to qsort), use this accessor. */
455 vec_t
<T
>::address (void)
461 /* Get the final element of the vector, which must not be empty. */
465 vec_t
<T
>::last (ALONE_VEC_CHECK_DECL
)
467 VEC_ASSERT (prefix_
.num_
, "last", T
, base
);
468 return (*this)[prefix_
.num_
- 1];
472 /* Index into vector. Return the IX'th element. IX must be in the
473 domain of the vector. */
477 vec_t
<T
>::operator[] (unsigned ix
) const
479 gcc_assert (ix
< prefix_
.num_
);
485 vec_t
<T
>::operator[] (unsigned ix
)
487 gcc_assert (ix
< prefix_
.num_
);
492 /* Return iteration condition and update PTR to point to the IX'th
493 element of VEC. Use this to iterate over the elements of a vector
496 for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
499 FIXME. This is a static member function because if VEC is NULL,
500 PTR should be initialized to NULL. This will become a regular
501 member function of the handler class. */
505 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
*ptr
)
507 if (vec
&& ix
< vec
->prefix_
.num_
)
509 *ptr
= vec
->vec_
[ix
];
520 /* Return iteration condition and update *PTR to point to the
521 IX'th element of VEC. Use this to iterate over the elements of a
524 for (ix = 0; v->iterate(ix, &ptr); ix++)
527 This variant is for vectors of objects. FIXME, to be removed
528 once the distinction between vec_t<T> and vec_t<T *> disappears. */
532 vec_t
<T
>::iterate (const vec_t
<T
> *vec
, unsigned ix
, T
**ptr
)
534 if (vec
&& ix
< vec
->prefix_
.num_
)
536 *ptr
= CONST_CAST (T
*, &vec
->vec_
[ix
]);
547 /* Convenience macro for forward iteration. */
549 #define FOR_EACH_VEC_ELT(T, V, I, P) \
550 for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))
552 /* Likewise, but start from FROM rather than 0. */
554 #define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM) \
555 for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))
557 /* Convenience macro for reverse iteration. */
559 #define FOR_EACH_VEC_ELT_REVERSE(T, V, I, P) \
560 for (I = VEC_length (T, (V)) - 1; \
561 VEC_iterate (T, (V), (I), (P)); \
565 /* Return the number of bytes needed to embed an instance of vec_t inside
566 another data structure.
568 Use these methods to determine the required size and initialization
569 of a vector V of type T embedded within another structure (as the
572 size_t vec_t<T>::embedded_size<T> (int reserve);
573 void v->embedded_init(int reserve, int active);
575 These allow the caller to perform the memory allocation. */
579 vec_t
<T
>::embedded_size (int nelems
)
581 return offsetof (vec_t
<T
>, vec_
) + nelems
* sizeof (T
);
585 /* Initialize the vector to contain room for NELEMS elements and
586 ACTIVE active elements. */
590 vec_t
<T
>::embedded_init (int nelems
, int active
)
592 prefix_
.num_
= active
;
593 prefix_
.alloc_
= nelems
;
597 /* Allocate a new vector with space for RESERVE objects. If RESERVE
598 is zero, NO vector is created.
600 Note that this allocator must always be a macro:
602 We support a vector which starts out with space on the stack and
603 switches to heap space when forced to reallocate. This works a
604 little differently. In the case of stack vectors, vec_alloc will
605 expand to a call to vec_alloc_1 that calls XALLOCAVAR to request the
606 initial allocation. This uses alloca to get the initial space.
607 Since alloca can not be usefully called in an inline function,
608 vec_alloc must always be a macro.
610 Important limitations of stack vectors:
612 - Only the initial allocation will be made using alloca, so pass a
613 reasonable estimate that doesn't use too much stack space; don't
616 - Don't return a stack-allocated vector from the function which
619 #define VEC_alloc(T,A,N) \
621 ? vec_t<T>::alloc (N, XALLOCAVAR (vec_t<T>, vec_t<T>::embedded_size (N)))\
622 : vec_t<T>::alloc<A> (N MEM_STAT_INFO))
625 template<enum vec_allocation_t A
>
627 vec_t
<T
>::alloc (int nelems MEM_STAT_DECL
)
629 return reserve_exact
<A
> ((vec_t
<T
> *) NULL
, nelems PASS_MEM_STAT
);
634 vec_t
<T
>::alloc (int nelems
, vec_t
<T
> *space
)
636 return static_cast <vec_t
<T
> *> (vec_stack_p_reserve_exact_1 (nelems
, space
));
640 /* Free vector *V and set it to NULL. */
643 template<enum vec_allocation_t A
>
645 vec_t
<T
>::free (vec_t
<T
> **v
)
660 /* Return a copy of this vector. The new and old vectors need not be
661 allocated by the same mechanism. */
664 template<enum vec_allocation_t A
>
666 vec_t
<T
>::copy (ALONE_MEM_STAT_DECL
)
668 unsigned len
= VEC_length (T
, this);
669 vec_t
<T
> *new_vec
= NULL
;
673 new_vec
= reserve_exact
<A
> (static_cast<vec_t
<T
> *> (NULL
),
675 new_vec
->embedded_init (len
, len
);
676 memcpy (new_vec
->address (), vec_
, sizeof (T
) * len
);
683 /* If this vector has space for RESERVE additional entries, return
684 true. You usually only need to use this if you are doing your
685 own vector reallocation, for instance on an embedded vector. This
686 returns true in exactly the same circumstances that vec_reserve
691 vec_t
<T
>::space (int nelems VEC_CHECK_DECL
)
693 VEC_ASSERT (nelems
>= 0, "space", T
, base
);
694 return prefix_
.alloc_
- prefix_
.num_
>= static_cast <unsigned> (nelems
);
698 /* Ensure that the vector **VEC has at least RESERVE slots available. This
699 will create additional headroom. Note this can cause **VEC to
700 be reallocated. Returns true iff reallocation actually occurred. */
703 template<enum vec_allocation_t A
>
705 vec_t
<T
>::reserve (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL MEM_STAT_DECL
)
707 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
710 *vec
= reserve
<A
> (*vec
, nelems PASS_MEM_STAT
);
716 /* Ensure that **VEC has at least NELEMS slots available. This will not
717 create additional headroom. Note this can cause VEC to be
718 reallocated. Returns true iff reallocation actually occurred. */
721 template<enum vec_allocation_t A
>
723 vec_t
<T
>::reserve_exact (vec_t
<T
> **vec
, int nelems VEC_CHECK_DECL
726 bool extend
= (*vec
) ? !(*vec
)->space (nelems VEC_CHECK_PASS
) : nelems
!= 0;
729 *vec
= reserve_exact
<A
> (*vec
, nelems PASS_MEM_STAT
);
735 /* Copy the elements from SRC to the end of this vector as if by memcpy.
736 SRC and this vector need not be allocated with the same mechanism,
737 although they most often will be. This vector is assumed to have
738 sufficient headroom available. */
742 vec_t
<T
>::splice (vec_t
<T
> *src VEC_CHECK_DECL
)
746 unsigned len
= VEC_length (T
, src
);
747 VEC_ASSERT (VEC_length (T
, this) + len
<= prefix_
.alloc_
, "splice", T
,
749 memcpy (address () + VEC_length (T
, this),
757 /* Copy the elements in SRC to the end of DST as if by memcpy. DST and
758 SRC need not be allocated with the same mechanism, although they most
759 often will be. DST need not have sufficient headroom and will be
760 reallocated if needed. */
763 template<enum vec_allocation_t A
>
765 vec_t
<T
>::safe_splice (vec_t
<T
> **dst
, vec_t
<T
> *src VEC_CHECK_DECL
770 reserve_exact
<A
> (dst
, VEC_length (T
, src
) VEC_CHECK_PASS MEM_STAT_INFO
);
771 (*dst
)->splice (src VEC_CHECK_PASS
);
776 /* Push OBJ (a new element) onto the end of the vector. There must be
777 sufficient space in the vector. Return a pointer to the slot
778 where OBJ was inserted. */
783 vec_t
<T
>::quick_push (const T
&obj VEC_CHECK_DECL
)
785 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "push", T
, base
);
786 T
*slot
= &vec_
[prefix_
.num_
++];
792 /* Push a new element OBJ onto the end of VEC. Reallocates VEC, if
793 needed. Return a pointer to the slot where OBJ was inserted. */
796 template<enum vec_allocation_t A
>
798 vec_t
<T
>::safe_push (vec_t
<T
> **vec
, const T
&obj VEC_CHECK_DECL MEM_STAT_DECL
)
800 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
801 return (*vec
)->quick_push (obj VEC_CHECK_PASS
);
805 /* Pop and return the last element off the end of the vector. */
810 vec_t
<T
>::pop (ALONE_VEC_CHECK_DECL
)
812 VEC_ASSERT (prefix_
.num_
, "pop", T
, base
);
813 return vec_
[--prefix_
.num_
];
817 /* Set the length of the vector to LEN. The new length must be less
818 than or equal to the current length. This is an O(1) operation. */
822 vec_t
<T
>::truncate (unsigned size VEC_CHECK_DECL
)
824 VEC_ASSERT (prefix_
.num_
>= size
, "truncate", T
, base
);
829 /* Grow the vector VEC to a specific length. The LEN must be as
830 long or longer than the current length. The new elements are
834 template<enum vec_allocation_t A
>
836 vec_t
<T
>::safe_grow (vec_t
<T
> **vec
, int size VEC_CHECK_DECL MEM_STAT_DECL
)
838 VEC_ASSERT (size
>= 0 && VEC_length (T
, *vec
) <= (unsigned)size
,
840 reserve_exact
<A
> (vec
, size
- (int)VEC_length (T
, *vec
)
841 VEC_CHECK_PASS PASS_MEM_STAT
);
842 (*vec
)->prefix_
.num_
= size
;
846 /* Grow the vector *VEC to a specific length. The LEN must be as
847 long or longer than the current length. The new elements are
848 initialized to zero. */
851 template<enum vec_allocation_t A
>
853 vec_t
<T
>::safe_grow_cleared (vec_t
<T
> **vec
, int size VEC_CHECK_DECL
856 int oldsize
= VEC_length (T
, *vec
);
857 safe_grow
<A
> (vec
, size VEC_CHECK_PASS PASS_MEM_STAT
);
858 memset (&((*vec
)->address ()[oldsize
]), 0, sizeof (T
) * (size
- oldsize
));
862 /* Replace the IXth element of this vector with a new value, VAL. */
866 vec_t
<T
>::replace (unsigned ix
, const T
&obj VEC_CHECK_DECL
)
868 VEC_ASSERT (ix
< prefix_
.num_
, "replace", T
, base
);
873 /* Insert an element, OBJ, at the IXth position of VEC. There must be
878 vec_t
<T
>::quick_insert (unsigned ix
, const T
&obj VEC_CHECK_DECL
)
880 VEC_ASSERT (prefix_
.num_
< prefix_
.alloc_
, "insert", T
, base
);
881 VEC_ASSERT (ix
<= prefix_
.num_
, "insert", T
, base
);
883 memmove (slot
+ 1, slot
, (prefix_
.num_
++ - ix
) * sizeof (T
));
888 /* Insert an element, OBJ, at the IXth position of VEC. Reallocate
889 VEC, if necessary. */
892 template<enum vec_allocation_t A
>
894 vec_t
<T
>::safe_insert (vec_t
<T
> **vec
, unsigned ix
, const T
&obj VEC_CHECK_DECL
897 reserve
<A
> (vec
, 1 VEC_CHECK_PASS PASS_MEM_STAT
);
898 (*vec
)->quick_insert (ix
, obj VEC_CHECK_PASS
);
902 /* Remove an element from the IXth position of this vector. Ordering of
903 remaining elements is preserved. This is an O(N) operation due to
908 vec_t
<T
>::ordered_remove (unsigned ix VEC_CHECK_DECL
)
910 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
912 memmove (slot
, slot
+ 1, (--prefix_
.num_
- ix
) * sizeof (T
));
916 /* Remove an element from the IXth position of VEC. Ordering of
917 remaining elements is destroyed. This is an O(1) operation. */
921 vec_t
<T
>::unordered_remove (unsigned ix VEC_CHECK_DECL
)
923 VEC_ASSERT (ix
< prefix_
.num_
, "remove", T
, base
);
924 vec_
[ix
] = vec_
[--prefix_
.num_
];
928 /* Remove LEN elements starting at the IXth. Ordering is retained.
929 This is an O(N) operation due to memmove. */
933 vec_t
<T
>::block_remove (unsigned ix
, unsigned len VEC_CHECK_DECL
)
935 VEC_ASSERT (ix
+ len
<= prefix_
.num_
, "block_remove", T
, base
);
938 memmove (slot
, slot
+ len
, (prefix_
.num_
- ix
) * sizeof (T
));
941 /* Sort the contents of V with qsort. Use CMP as the comparison function. */
942 #define VEC_qsort(T,V,CMP) \
943 qsort (VEC_address (T, V), VEC_length (T, V), sizeof (T), CMP)
946 /* Find and return the first position in which OBJ could be inserted
947 without changing the ordering of this vector. LESSTHAN is a
948 function that returns true if the first argument is strictly less
953 vec_t
<T
>::lower_bound (T obj
, bool (*lessthan
)(const T
&, const T
&)) const
955 unsigned int len
= VEC_length (T
, this);
956 unsigned int half
, middle
;
957 unsigned int first
= 0;
963 T middle_elem
= (*this)[middle
];
964 if (lessthan (middle_elem
, obj
))
968 len
= len
- half
- 1;
977 void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
978 void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL
);
980 /* Ensure there are at least RESERVE free slots in VEC_, growing
981 exponentially. If RESERVE < 0 grow exactly, else grow
982 exponentially. As a special case, if VEC_ is NULL, and RESERVE is
983 0, no vector will be created. */
986 template<enum vec_allocation_t A
>
988 vec_t
<T
>::reserve (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
991 size_t off
= offsetof (vec_t
<T
>, vec_
);
992 size_t sz
= sizeof (T
);
997 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1000 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, false PASS_MEM_STAT
);
1003 res
= vec_stack_o_reserve (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1007 return static_cast <vec_t
<T
> *> (res
);
1011 /* Ensure there are at least RESERVE free slots in VEC, growing
1012 exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
1013 a special case, if VEC is NULL, and RESERVE is 0, no vector will be
1016 template<typename T
>
1017 template<enum vec_allocation_t A
>
1019 vec_t
<T
>::reserve_exact (vec_t
<T
> *vec
, int reserve MEM_STAT_DECL
)
1022 size_t off
= sizeof (struct vec_prefix
);
1023 size_t sz
= sizeof (T
);
1025 gcc_assert (offsetof (vec_t
<T
>, vec_
) == sizeof (struct vec_prefix
));
1030 res
= vec_gc_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1033 res
= vec_heap_o_reserve_1 (vec
, reserve
, off
, sz
, true PASS_MEM_STAT
);
1036 res
= vec_stack_o_reserve_exact (vec
, reserve
, off
, sz PASS_MEM_STAT
);
1040 return static_cast <vec_t
<T
> *> (res
);
1043 #endif /* GCC_VEC_H */