var-tracking.c (vt_add_function_parameter): Adjust for VEC changes.
[official-gcc.git] / gcc / vec.h
blob88891d74d7fad43aa131dffa4ce88be9b01aed32
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
12 version.
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
17 for more details.
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/>. */
23 #ifndef GCC_VEC_H
24 #define GCC_VEC_H
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
49 by value.
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,
117 struct my_struct {
118 vec_t<tree> *v; // A (pointer to) a vector of tree pointers.
121 struct my_struct *s;
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 }
130 #if ENABLE_CHECKING
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)
142 ATTRIBUTE_NORETURN;
143 #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
144 #else
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)
152 #endif
154 #define VEC(T,A) vec_t<T>
156 enum vec_allocation_t { heap, gc, stack };
158 struct vec_prefix
160 unsigned num_;
161 unsigned alloc_;
164 /* Vector type, user visible. */
165 template<typename T>
166 struct GTY(()) vec_t
168 unsigned length (void) const;
169 bool empty (void) const;
170 T *address (void);
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
217 MEM_STAT_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
230 MEM_STAT_DECL);
232 static bool iterate (const vec_t<T> *, unsigned, T *);
233 static bool iterate (const vec_t<T> *, unsigned, T **);
235 vec_prefix prefix_;
236 T vec_[1];
240 /* Garbage collection support for vec_t. */
242 template<typename T>
243 void
244 gt_ggc_mx (vec_t<T> *v)
246 extern void gt_ggc_mx (T &);
247 for (unsigned i = 0; i < v->length (); i++)
248 gt_ggc_mx ((*v)[i]);
252 /* PCH support for vec_t. */
254 template<typename T>
255 void
256 gt_pch_nx (vec_t<T> *v)
258 extern void gt_pch_nx (T &);
259 for (unsigned i = 0; i < v->length (); i++)
260 gt_pch_nx ((*v)[i]);
263 template<typename T>
264 void
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);
271 template<typename T>
272 void
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> \
311 void \
312 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
316 template<typename T> \
317 void \
318 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
322 template<typename T> \
323 void \
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
337 MEM_STAT_DECL);
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) \
353 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. */
361 template<typename T>
362 static inline 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) \
372 ((*(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) \
414 (V \
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. */
449 template<typename T>
450 inline unsigned
451 vec_t<T>::length (void) const
453 return prefix_.num_;
457 /* Return true if this vector has no active elements. */
459 template<typename T>
460 inline bool
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. */
471 template<typename T>
472 inline T *
473 vec_t<T>::address (void)
475 return vec_;
479 /* Get the final element of the vector, which must not be empty. */
481 template<typename T>
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. */
493 template<typename T>
494 const T &
495 vec_t<T>::operator[] (unsigned ix) const
497 gcc_assert (ix < prefix_.num_);
498 return vec_[ix];
501 template<typename T>
503 vec_t<T>::operator[] (unsigned ix)
505 gcc_assert (ix < prefix_.num_);
506 return vec_[ix];
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
512 as follows,
514 for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
515 continue;
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. */
521 template<typename T>
522 bool
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];
528 return true;
530 else
532 *ptr = 0;
533 return false;
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
540 vector as follows,
542 for (ix = 0; v->iterate(ix, &ptr); ix++)
543 continue;
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. */
548 template<typename T>
549 bool
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]);
555 return true;
557 else
559 *ptr = 0;
560 return false;
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)); \
580 (I)--)
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
588 final member):
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. */
595 template<typename T>
596 size_t
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. */
606 template<typename T>
607 void
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
632 pass zero.
634 - Don't return a stack-allocated vector from the function which
635 allocated it. */
637 #define VEC_alloc(T,A,N) \
638 ((A == stack) \
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))
642 template<typename T>
643 template<enum vec_allocation_t A>
644 vec_t<T> *
645 vec_t<T>::alloc (int nelems MEM_STAT_DECL)
647 return reserve_exact<A> ((vec_t<T> *) NULL, nelems PASS_MEM_STAT);
650 template<typename T>
651 vec_t<T> *
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. */
660 template<typename T>
661 template<enum vec_allocation_t A>
662 void
663 vec_t<T>::free (vec_t<T> **v)
665 if (*v)
667 if (A == heap)
668 vec_heap_free (*v);
669 else if (A == gc)
670 ggc_free (*v);
671 else if (A == stack)
672 vec_stack_free (*v);
674 *v = NULL;
678 /* Return a copy of this vector. The new and old vectors need not be
679 allocated by the same mechanism. */
681 template<typename T>
682 template<enum vec_allocation_t A>
683 vec_t<T> *
684 vec_t<T>::copy (ALONE_MEM_STAT_DECL)
686 unsigned len = VEC_length (T, this);
687 vec_t<T> *new_vec = NULL;
689 if (len)
691 new_vec = reserve_exact<A> (static_cast<vec_t<T> *> (NULL),
692 len PASS_MEM_STAT);
693 new_vec->embedded_init (len, len);
694 memcpy (new_vec->address (), vec_, sizeof (T) * len);
697 return new_vec;
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
705 will. */
707 template<typename T>
708 bool
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. */
720 template<typename T>
721 template<enum vec_allocation_t A>
722 bool
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;
727 if (extend)
728 *vec = reserve<A> (*vec, nelems PASS_MEM_STAT);
730 return extend;
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. */
738 template<typename T>
739 template<enum vec_allocation_t A>
740 bool
741 vec_t<T>::reserve_exact (vec_t<T> **vec, int nelems VEC_CHECK_DECL
742 MEM_STAT_DECL)
744 bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
746 if (extend)
747 *vec = reserve_exact<A> (*vec, nelems PASS_MEM_STAT);
749 return extend;
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. */
758 template<typename T>
759 void
760 vec_t<T>::splice (vec_t<T> *src VEC_CHECK_DECL)
762 if (src)
764 unsigned len = VEC_length (T, src);
765 VEC_ASSERT (VEC_length (T, this) + len <= prefix_.alloc_, "splice", T,
766 base);
767 memcpy (address () + VEC_length (T, this),
768 src->address (),
769 len * sizeof (T));
770 prefix_.num_ += len;
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. */
780 template<typename T>
781 template<enum vec_allocation_t A>
782 void
783 vec_t<T>::safe_splice (vec_t<T> **dst, vec_t<T> *src VEC_CHECK_DECL
784 MEM_STAT_DECL)
786 if (src)
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. */
799 template<typename T>
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_++];
805 *slot = obj;
806 return slot;
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. */
813 template<typename T>
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. */
826 template<typename T>
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. */
838 template<typename T>
839 void
840 vec_t<T>::truncate (unsigned size VEC_CHECK_DECL)
842 VEC_ASSERT (prefix_.num_ >= size, "truncate", T, base);
843 prefix_.num_ = size;
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
849 uninitialized. */
851 template<typename T>
852 template<enum vec_allocation_t A>
853 void
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,
857 "grow", T, A);
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. */
868 template<typename T>
869 template<enum vec_allocation_t A>
870 void
871 vec_t<T>::safe_grow_cleared (vec_t<T> **vec, int size VEC_CHECK_DECL
872 MEM_STAT_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. */
882 template<typename T>
883 void
884 vec_t<T>::replace (unsigned ix, const T &obj VEC_CHECK_DECL)
886 VEC_ASSERT (ix < prefix_.num_, "replace", T, base);
887 vec_[ix] = obj;
891 /* Insert an element, OBJ, at the IXth position of VEC. There must be
892 sufficient space. */
894 template<typename T>
895 void
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);
900 T *slot = &vec_[ix];
901 memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
902 *slot = obj;
906 /* Insert an element, OBJ, at the IXth position of VEC. Reallocate
907 VEC, if necessary. */
909 template<typename T>
910 template<enum vec_allocation_t A>
911 void
912 vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, const T &obj VEC_CHECK_DECL
913 MEM_STAT_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
922 a memmove. */
924 template<typename T>
925 void
926 vec_t<T>::ordered_remove (unsigned ix VEC_CHECK_DECL)
928 VEC_ASSERT (ix < prefix_.num_, "remove", T, base);
929 T *slot = &vec_[ix];
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. */
937 template<typename T>
938 void
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. */
949 template<typename T>
950 void
951 vec_t<T>::block_remove (unsigned ix, unsigned len VEC_CHECK_DECL)
953 VEC_ASSERT (ix + len <= prefix_.num_, "block_remove", T, base);
954 T *slot = &vec_[ix];
955 prefix_.num_ -= len;
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
967 than the second. */
969 template<typename T>
970 unsigned
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;
976 while (len > 0)
978 half = len / 2;
979 middle = first;
980 middle += half;
981 T middle_elem = (*this)[middle];
982 if (lessthan (middle_elem, obj))
984 first = middle;
985 ++first;
986 len = len - half - 1;
988 else
989 len = half;
991 return first;
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>
1005 vec_t<T> *
1006 vec_t<T>::reserve (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1008 void *res = NULL;
1009 size_t off = offsetof (vec_t<T>, vec_);
1010 size_t sz = sizeof (T);
1012 switch (A)
1014 case gc:
1015 res = vec_gc_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
1016 break;
1017 case heap:
1018 res = vec_heap_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
1019 break;
1020 case stack:
1021 res = vec_stack_o_reserve (vec, reserve, off, sz PASS_MEM_STAT);
1022 break;
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
1032 created. */
1034 template<typename T>
1035 template<enum vec_allocation_t A>
1036 vec_t<T> *
1037 vec_t<T>::reserve_exact (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1039 void *res = NULL;
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));
1045 switch (A)
1047 case gc:
1048 res = vec_gc_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1049 break;
1050 case heap:
1051 res = vec_heap_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1052 break;
1053 case stack:
1054 res = vec_stack_o_reserve_exact (vec, reserve, off, sz PASS_MEM_STAT);
1055 break;
1058 return static_cast <vec_t<T> *> (res);
1061 #endif /* GCC_VEC_H */