This patch works around a parsing problem with g++ 4.3. The parser is
[official-gcc.git] / gcc / vec.h
blobc0f1bb2cd2130114730f0d2303eee9570a0ad1ef
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);
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
221 MEM_STAT_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
237 MEM_STAT_DECL);
239 template<enum vec_allocation_t A>
240 static void safe_insert (vec_t<T> **, unsigned, T obj VEC_CHECK_DECL
241 MEM_STAT_DECL);
243 static bool iterate (const vec_t<T> *, unsigned, T *);
244 static bool iterate (const vec_t<T> *, unsigned, T **);
246 vec_prefix prefix_;
247 T vec_[1];
251 /* Garbage collection support for vec_t. */
253 template<typename T>
254 void
255 gt_ggc_mx (vec_t<T> *v)
257 extern void gt_ggc_mx (T &);
258 for (unsigned i = 0; i < v->length (); i++)
259 gt_ggc_mx ((*v)[i]);
263 /* PCH support for vec_t. */
265 template<typename T>
266 void
267 gt_pch_nx (vec_t<T> *v)
269 extern void gt_pch_nx (T &);
270 for (unsigned i = 0; i < v->length (); i++)
271 gt_pch_nx ((*v)[i]);
274 template<typename T>
275 void
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);
282 template<typename T>
283 void
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> \
322 void \
323 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
327 template<typename T> \
328 void \
329 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \
333 template<typename T> \
334 void \
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
348 MEM_STAT_DECL);
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) \
364 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. */
372 template<typename T>
373 static inline 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) \
383 ((*(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) \
425 (V \
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. */
460 template<typename T>
461 inline unsigned
462 vec_t<T>::length (void) const
464 return prefix_.num_;
468 /* Return true if this vector has no active elements. */
470 template<typename T>
471 inline bool
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. */
482 template<typename T>
483 inline T *
484 vec_t<T>::address (void)
486 return vec_;
490 /* Get the final element of the vector, which must not be empty. */
492 template<typename T>
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. */
504 template<typename T>
505 const T &
506 vec_t<T>::operator[] (unsigned ix) const
508 gcc_assert (ix < prefix_.num_);
509 return vec_[ix];
512 template<typename T>
514 vec_t<T>::operator[] (unsigned ix)
516 gcc_assert (ix < prefix_.num_);
517 return vec_[ix];
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
523 as follows,
525 for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
526 continue;
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. */
532 template<typename T>
533 bool
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];
539 return true;
541 else
543 *ptr = 0;
544 return false;
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
551 vector as follows,
553 for (ix = 0; v->iterate(ix, &ptr); ix++)
554 continue;
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. */
559 template<typename T>
560 bool
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]);
566 return true;
568 else
570 *ptr = 0;
571 return false;
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)); \
591 (I)--)
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
599 final member):
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. */
606 template<typename T>
607 size_t
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. */
617 template<typename T>
618 void
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
643 pass zero.
645 - Don't return a stack-allocated vector from the function which
646 allocated it. */
648 #define VEC_alloc(T,A,N) \
649 ((A == stack) \
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))
653 template<typename T>
654 template<enum vec_allocation_t A>
655 vec_t<T> *
656 vec_t<T>::alloc (int nelems MEM_STAT_DECL)
658 return reserve_exact<A> ((vec_t<T> *) NULL, nelems PASS_MEM_STAT);
661 template<typename T>
662 vec_t<T> *
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. */
671 template<typename T>
672 template<enum vec_allocation_t A>
673 void
674 vec_t<T>::free (vec_t<T> **v)
676 if (*v)
678 if (A == heap)
679 vec_heap_free (*v);
680 else if (A == gc)
681 ggc_free (*v);
682 else if (A == stack)
683 vec_stack_free (*v);
685 *v = NULL;
689 /* Return a copy of this vector. The new and old vectors need not be
690 allocated by the same mechanism. */
692 template<typename T>
693 template<enum vec_allocation_t A>
694 vec_t<T> *
695 vec_t<T>::copy (ALONE_MEM_STAT_DECL)
697 unsigned len = VEC_length (T, this);
698 vec_t<T> *new_vec = NULL;
700 if (len)
702 new_vec = reserve_exact<A> (static_cast<vec_t<T> *> (NULL),
703 len PASS_MEM_STAT);
704 new_vec->embedded_init (len, len);
705 memcpy (new_vec->address (), vec_, sizeof (T) * len);
708 return new_vec;
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
716 will. */
718 template<typename T>
719 bool
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. */
731 template<typename T>
732 template<enum vec_allocation_t A>
733 bool
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;
738 if (extend)
739 *vec = reserve<A> (*vec, nelems PASS_MEM_STAT);
741 return extend;
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. */
749 template<typename T>
750 template<enum vec_allocation_t A>
751 bool
752 vec_t<T>::reserve_exact (vec_t<T> **vec, int nelems VEC_CHECK_DECL
753 MEM_STAT_DECL)
755 bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
757 if (extend)
758 *vec = reserve_exact<A> (*vec, nelems PASS_MEM_STAT);
760 return extend;
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. */
769 template<typename T>
770 void
771 vec_t<T>::splice (vec_t<T> *src VEC_CHECK_DECL)
773 if (src)
775 unsigned len = VEC_length (T, src);
776 VEC_ASSERT (VEC_length (T, this) + len <= prefix_.alloc_, "splice", T,
777 base);
778 memcpy (address () + VEC_length (T, this),
779 src->address (),
780 len * sizeof (T));
781 prefix_.num_ += len;
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. */
791 template<typename T>
792 template<enum vec_allocation_t A>
793 void
794 vec_t<T>::safe_splice (vec_t<T> **dst, vec_t<T> *src VEC_CHECK_DECL
795 MEM_STAT_DECL)
797 if (src)
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. */
808 template<typename T>
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_];
815 prefix_.num_++;
816 return val;
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. */
825 template<typename T>
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_++];
831 if (ptr)
832 *slot = *ptr;
833 return slot;
837 /* Push a new element OBJ onto the end of VEC. Returns a reference to
838 the slot filled in. Reallocates V, if needed. */
840 template<typename T>
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. */
855 template<typename T>
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. */
868 template<typename T>
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. */
880 template<typename T>
881 void
882 vec_t<T>::truncate (unsigned size VEC_CHECK_DECL)
884 VEC_ASSERT (prefix_.num_ >= size, "truncate", T, base);
885 prefix_.num_ = size;
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
891 uninitialized. */
893 template<typename T>
894 template<enum vec_allocation_t A>
895 void
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,
899 "grow", T, A);
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. */
910 template<typename T>
911 template<enum vec_allocation_t A>
912 void
913 vec_t<T>::safe_grow_cleared (vec_t<T> **vec, int size VEC_CHECK_DECL
914 MEM_STAT_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. */
924 template<typename T>
925 void
926 vec_t<T>::replace (unsigned ix, T obj VEC_CHECK_DECL)
928 VEC_ASSERT (ix < prefix_.num_, "replace", T, base);
929 vec_[ix] = obj;
933 /* Insert an element, OBJ, at the IXth position of VEC. There must be
934 sufficient space. */
936 template<typename T>
937 void
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);
942 T *slot = &vec_[ix];
943 memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
944 *slot = obj;
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. */
952 template<typename T>
953 void
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);
958 T *slot = &vec_[ix];
959 memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
960 if (ptr)
961 *slot = *ptr;
965 /* Insert an element, VAL, at the IXth position of VEC. Reallocate
966 VEC, if necessary. */
968 template<typename T>
969 template<enum vec_allocation_t A>
970 void
971 vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, T obj VEC_CHECK_DECL
972 MEM_STAT_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. */
984 template<typename T>
985 template<enum vec_allocation_t A>
986 void
987 vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, T *ptr VEC_CHECK_DECL
988 MEM_STAT_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
997 a memmove. */
999 template<typename T>
1000 void
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>
1013 void
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>
1025 void
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
1042 than the second. */
1044 template<typename T>
1045 unsigned
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;
1051 while (len > 0)
1053 half = len >> 1;
1054 middle = first;
1055 middle += half;
1056 T middle_elem = (*this)[middle];
1057 if (lessthan (middle_elem, obj))
1059 first = middle;
1060 ++first;
1061 len = len - half - 1;
1063 else
1064 len = half;
1066 return first;
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
1073 than the second. */
1075 template<typename T>
1076 unsigned
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;
1083 while (len > 0)
1085 half = len >> 1;
1086 middle = first;
1087 middle += half;
1088 const T *middle_elem = &(*this)[middle];
1089 if (lessthan (middle_elem, ptr))
1091 first = middle;
1092 ++first;
1093 len = len - half - 1;
1095 else
1096 len = half;
1098 return first;
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>
1112 vec_t<T> *
1113 vec_t<T>::reserve (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1115 void *res = NULL;
1116 size_t off = offsetof (vec_t<T>, vec_);
1117 size_t sz = sizeof (T);
1119 switch (A)
1121 case gc:
1122 res = vec_gc_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
1123 break;
1124 case heap:
1125 res = vec_heap_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
1126 break;
1127 case stack:
1128 res = vec_stack_o_reserve (vec, reserve, off, sz PASS_MEM_STAT);
1129 break;
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
1139 created. */
1141 template<typename T>
1142 template<enum vec_allocation_t A>
1143 vec_t<T> *
1144 vec_t<T>::reserve_exact (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1146 void *res = NULL;
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));
1152 switch (A)
1154 case gc:
1155 res = vec_gc_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1156 break;
1157 case heap:
1158 res = vec_heap_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1159 break;
1160 case stack:
1161 res = vec_stack_o_reserve_exact (vec, reserve, off, sz PASS_MEM_STAT);
1162 break;
1165 return static_cast <vec_t<T> *> (res);
1168 #endif /* GCC_VEC_H */