Merge trunk version 193672 into gupc branch.
[official-gcc.git] / gcc / vec.h
blob61ae9bfb2f9be35ae3767e9a219c770e2dac9617
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 /* FIXME - When compiling some of the gen* binaries, we cannot enable GC
27 support because the headers generated by gengtype are still not
28 present. In particular, the header file gtype-desc.h is missing,
29 so compilation may fail if we try to include ggc.h.
31 Since we use some of those declarations, we need to provide them
32 (even if the GC-based templates are not used). This is not a
33 problem because the code that runs before gengtype is built will
34 never need to use GC vectors. But it does force us to declare
35 these functions more than once. */
36 #ifdef GENERATOR_FILE
37 #define VEC_GC_ENABLED 0
38 #else
39 #define VEC_GC_ENABLED 1
40 #endif // GENERATOR_FILE
42 #include "statistics.h" // For CXX_MEM_STAT_INFO.
44 #if VEC_GC_ENABLED
45 #include "ggc.h"
46 #else
47 # ifndef GCC_GGC_H
48 /* Even if we think that GC is not enabled, the test that sets it is
49 weak. There are files compiled with -DGENERATOR_FILE that already
50 include ggc.h. We only need to provide these definitions if ggc.h
51 has not been included. Sigh. */
52 extern void ggc_free (void *);
53 extern size_t ggc_round_alloc_size (size_t requested_size);
54 extern void *ggc_internal_cleared_alloc_stat (size_t MEM_STAT_DECL)
55 ATTRIBUTE_MALLOC;
56 extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
57 # endif // GCC_GGC_H
58 #endif // VEC_GC_ENABLED
60 /* Templated vector type and associated interfaces.
62 The interface functions are typesafe and use inline functions,
63 sometimes backed by out-of-line generic functions. The vectors are
64 designed to interoperate with the GTY machinery.
66 There are both 'index' and 'iterate' accessors. The index accessor
67 is implemented by operator[]. The iterator returns a boolean
68 iteration condition and updates the iteration variable passed by
69 reference. Because the iterator will be inlined, the address-of
70 can be optimized away.
72 Each operation that increases the number of active elements is
73 available in 'quick' and 'safe' variants. The former presumes that
74 there is sufficient allocated space for the operation to succeed
75 (it dies if there is not). The latter will reallocate the
76 vector, if needed. Reallocation causes an exponential increase in
77 vector size. If you know you will be adding N elements, it would
78 be more efficient to use the reserve operation before adding the
79 elements with the 'quick' operation. This will ensure there are at
80 least as many elements as you ask for, it will exponentially
81 increase if there are too few spare slots. If you want reserve a
82 specific number of slots, but do not want the exponential increase
83 (for instance, you know this is the last allocation), use the
84 reserve_exact operation. You can also create a vector of a
85 specific size from the get go.
87 You should prefer the push and pop operations, as they append and
88 remove from the end of the vector. If you need to remove several
89 items in one go, use the truncate operation. The insert and remove
90 operations allow you to change elements in the middle of the
91 vector. There are two remove operations, one which preserves the
92 element ordering 'ordered_remove', and one which does not
93 'unordered_remove'. The latter function copies the end element
94 into the removed slot, rather than invoke a memmove operation. The
95 'lower_bound' function will determine where to place an item in the
96 array using insert that will maintain sorted order.
98 Vectors are template types with three arguments: the type of the
99 elements in the vector, the allocation strategy, and the physical
100 layout to use
102 Four allocation strategies are supported:
104 - Heap: allocation is done using malloc/free. This is the
105 default allocation strategy.
107 - Stack: allocation is done using alloca.
109 - GC: allocation is done using ggc_alloc/ggc_free.
111 - GC atomic: same as GC with the exception that the elements
112 themselves are assumed to be of an atomic type that does
113 not need to be garbage collected. This means that marking
114 routines do not need to traverse the array marking the
115 individual elements. This increases the performance of
116 GC activities.
118 Two physical layouts are supported:
120 - Embedded: The vector is structured using the trailing array
121 idiom. The last member of the structure is an array of size
122 1. When the vector is initially allocated, a single memory
123 block is created to hold the vector's control data and the
124 array of elements. These vectors cannot grow without
125 reallocation (see discussion on embeddable vectors below).
127 - Space efficient: The vector is structured as a pointer to an
128 embedded vector. This is the default layout. It means that
129 vectors occupy a single word of storage before initial
130 allocation. Vectors are allowed to grow (the internal
131 pointer is reallocated but the main vector instance does not
132 need to relocate).
134 The type, allocation and layout are specified when the vector is
135 declared.
137 If you need to directly manipulate a vector, then the 'address'
138 accessor will return the address of the start of the vector. Also
139 the 'space' predicate will tell you whether there is spare capacity
140 in the vector. You will not normally need to use these two functions.
142 Notes on the different layout strategies
144 * Embeddable vectors (vec<T, A, vl_embed>)
146 These vectors are suitable to be embedded in other data
147 structures so that they can be pre-allocated in a contiguous
148 memory block.
150 Embeddable vectors are implemented using the trailing array
151 idiom, thus they are not resizeable without changing the address
152 of the vector object itself. This means you cannot have
153 variables or fields of embeddable vector type -- always use a
154 pointer to a vector. The one exception is the final field of a
155 structure, which could be a vector type.
157 You will have to use the embedded_size & embedded_init calls to
158 create such objects, and they will not be resizeable (so the
159 'safe' allocation variants are not available).
161 Properties of embeddable vectors:
163 - The whole vector and control data are allocated in a single
164 contiguous block. It uses the trailing-vector idiom, so
165 allocation must reserve enough space for all the elements
166 in the vector plus its control data.
167 - The vector cannot be re-allocated.
168 - The vector cannot grow nor shrink.
169 - No indirections needed for access/manipulation.
170 - It requires 2 words of storage (prior to vector allocation).
173 * Space efficient vector (vec<T, A, vl_ptr>)
175 These vectors can grow dynamically and are allocated together
176 with their control data. They are suited to be included in data
177 structures. Prior to initial allocation, they only take a single
178 word of storage.
180 These vectors are implemented as a pointer to embeddable vectors.
181 The semantics allow for this pointer to be NULL to represent
182 empty vectors. This way, empty vectors occupy minimal space in
183 the structure containing them.
185 Properties:
187 - The whole vector and control data are allocated in a single
188 contiguous block.
189 - The whole vector may be re-allocated.
190 - Vector data may grow and shrink.
191 - Access and manipulation requires a pointer test and
192 indirection.
193 - It requires 1 word of storage (prior to vector allocation).
195 An example of their use would be,
197 struct my_struct {
198 // A space-efficient vector of tree pointers in GC memory.
199 vec<tree, va_gc, vl_ptr> v;
202 struct my_struct *s;
204 if (s->v.length ()) { we have some contents }
205 s->v.safe_push (decl); // append some decl onto the end
206 for (ix = 0; s->v.iterate (ix, &elt); ix++)
207 { do something with elt }
210 /* Support function for statistics. */
211 extern void dump_vec_loc_statistics (void);
214 /* Control data for vectors. This contains the number of allocated
215 and used slots inside a vector. */
217 class vec_prefix
219 /* FIXME - These fields should be private, but we need to cater to
220 compilers that have stricter notions of PODness for types. */
221 public:
222 /* Memory allocation support routines in vec.c. */
223 void register_overhead_PRIVATE_ (size_t, const char *, int, const char *);
224 void release_overhead_PRIVATE_ (void);
225 static unsigned calculate_allocation_PRIVATE_ (vec_prefix *, unsigned, bool);
227 /* Note that vec_prefix should be a base class for vec, but we use
228 offsetof() on vector fields of tree structures (e.g.,
229 tree_binfo::base_binfos), and offsetof only supports base types.
231 To compensate, we make vec_prefix a field inside vec and make
232 vec a friend class of vec_prefix so it can access its fields. */
233 template <typename, typename, typename> friend class vec;
235 /* The allocator types also need access to our internals. */
236 friend struct va_gc;
237 friend struct va_gc_atomic;
238 friend struct va_heap;
239 friend struct va_stack;
241 unsigned alloc_PRIVATE_;
242 unsigned num_PRIVATE_;
245 template<typename, typename, typename> class vec;
247 /* Valid vector layouts
249 vl_embed - Embeddable vector that uses the trailing array idiom.
250 vl_ptr - Space efficient vector that uses a pointer to an
251 embeddable vector. */
252 struct vl_embed { };
253 struct vl_ptr { };
256 /* Types of supported allocations
258 va_heap - Allocation uses malloc/free.
259 va_gc - Allocation uses ggc_alloc.
260 va_gc_atomic - Same as GC, but individual elements of the array
261 do not need to be marked during collection.
262 va_stack - Allocation uses alloca. */
264 /* Allocator type for heap vectors. */
265 struct va_heap
267 /* Heap vectors are frequently regular instances, so use the vl_ptr
268 layout for them. */
269 typedef vl_ptr default_layout;
271 template<typename T>
272 static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool
273 CXX_MEM_STAT_INFO);
275 template<typename T>
276 static void release (vec<T, va_heap, vl_embed> *&);
280 /* Allocator for heap memory. Ensure there are at least RESERVE free
281 slots in V. If EXACT is true, grow exactly, else grow
282 exponentially. As a special case, if the vector had not been
283 allocated and and RESERVE is 0, no vector will be created. */
285 template<typename T>
286 inline void
287 va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
288 MEM_STAT_DECL)
290 unsigned alloc = vec_prefix::calculate_allocation_PRIVATE_ (
291 v ? &v->pfx_PRIVATE_ : 0, reserve, exact);
292 if (!alloc)
294 release (v);
295 return;
298 if (GATHER_STATISTICS && v)
299 v->pfx_PRIVATE_.release_overhead_PRIVATE_ ();
301 size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
302 unsigned nelem = v ? v->length () : 0;
303 v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size));
304 v->embedded_init (alloc, nelem);
306 if (GATHER_STATISTICS)
307 v->pfx_PRIVATE_.register_overhead_PRIVATE_ (size FINAL_PASS_MEM_STAT);
311 /* Free the heap space allocated for vector V. */
313 template<typename T>
314 void
315 va_heap::release (vec<T, va_heap, vl_embed> *&v)
317 if (v == NULL)
318 return;
320 if (GATHER_STATISTICS)
321 v->pfx_PRIVATE_.release_overhead_PRIVATE_ ();
322 ::free (v);
323 v = NULL;
327 /* Allocator type for GC vectors. Notice that we need the structure
328 declaration even if GC is not enabled. */
330 struct va_gc
332 /* Use vl_embed as the default layout for GC vectors. Due to GTY
333 limitations, GC vectors must always be pointers, so it is more
334 efficient to use a pointer to the vl_embed layout, rather than
335 using a pointer to a pointer as would be the case with vl_ptr. */
336 typedef vl_embed default_layout;
338 template<typename T, typename A>
339 static void reserve (vec<T, A, vl_embed> *&, unsigned, bool
340 CXX_MEM_STAT_INFO);
342 template<typename T, typename A>
343 static void release (vec<T, A, vl_embed> *&v) { v = NULL; }
347 /* Allocator for GC memory. Ensure there are at least RESERVE free
348 slots in V. If EXACT is true, grow exactly, else grow
349 exponentially. As a special case, if the vector had not been
350 allocated and and RESERVE is 0, no vector will be created. */
352 template<typename T, typename A>
353 void
354 va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
355 MEM_STAT_DECL)
357 unsigned alloc = vec_prefix::calculate_allocation_PRIVATE_ (
358 v ? &v->pfx_PRIVATE_ : 0, reserve, exact);
359 if (!alloc)
361 ::ggc_free (v);
362 v = NULL;
363 return;
366 /* Calculate the amount of space we want. */
367 size_t size = vec<T, A, vl_embed>::embedded_size (alloc);
369 /* Ask the allocator how much space it will really give us. */
370 size = ggc_round_alloc_size (size);
372 /* Adjust the number of slots accordingly. */
373 size_t vec_offset = sizeof (vec_prefix);
374 size_t elt_size = sizeof (T);
375 alloc = (size - vec_offset) / elt_size;
377 /* And finally, recalculate the amount of space we ask for. */
378 size = vec_offset + alloc * elt_size;
380 unsigned nelem = v ? v->length () : 0;
381 v = static_cast <vec<T, A, vl_embed> *> (ggc_realloc_stat (v, size));
382 v->embedded_init (alloc, nelem);
386 /* Allocator type for GC vectors. This is for vectors of types
387 atomics w.r.t. collection, so allocation and deallocation is
388 completely inherited from va_gc. */
389 struct va_gc_atomic : va_gc
394 /* Allocator type for stack vectors. */
395 struct va_stack
397 /* Use vl_ptr as the default layout for stack vectors. */
398 typedef vl_ptr default_layout;
400 template<typename T>
401 static void alloc (vec<T, va_stack, vl_ptr>&, unsigned,
402 vec<T, va_stack, vl_embed> *);
404 template <typename T>
405 static void reserve (vec<T, va_stack, vl_embed> *&, unsigned, bool
406 CXX_MEM_STAT_INFO);
408 template <typename T>
409 static void release (vec<T, va_stack, vl_embed> *&);
412 /* Helper functions to keep track of vectors allocated on the stack. */
413 void register_stack_vec (void *);
414 int stack_vec_register_index (void *);
415 void unregister_stack_vec (unsigned);
417 /* Allocate a vector V which uses alloca for the initial allocation.
418 SPACE is space allocated using alloca. NELEMS is the number of
419 entries allocated. */
421 template<typename T>
422 void
423 va_stack::alloc (vec<T, va_stack, vl_ptr> &v, unsigned nelems,
424 vec<T, va_stack, vl_embed> *space)
426 v.vec_PRIVATE_ = space;
427 register_stack_vec (static_cast<void *> (v.vec_PRIVATE_));
428 v.vec_PRIVATE_->embedded_init (nelems, 0);
432 /* Reserve NELEMS slots for a vector initially allocated on the stack.
433 When this happens, we switch back to heap allocation. We remove
434 the vector from stack_vecs, if it is there, since we no longer need
435 to avoid freeing it. If EXACT is true, grow exactly, otherwise
436 grow exponentially. */
438 template<typename T>
439 void
440 va_stack::reserve (vec<T, va_stack, vl_embed> *&v, unsigned nelems, bool exact
441 MEM_STAT_DECL)
443 int ix = stack_vec_register_index (static_cast<void *> (v));
444 if (ix >= 0)
445 unregister_stack_vec (ix);
446 else
448 /* V is already on the heap. */
449 va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v),
450 nelems, exact);
451 return;
454 /* Move VEC_ to the heap. */
455 nelems += v->pfx_PRIVATE_.num_PRIVATE_;
456 vec<T, va_stack, vl_embed> *oldvec = v;
457 v = NULL;
458 va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&>(v), nelems,
459 exact);
460 if (v && oldvec)
462 v->pfx_PRIVATE_.num_PRIVATE_ = oldvec->length ();
463 memcpy (v->data_PRIVATE_,
464 oldvec->data_PRIVATE_,
465 oldvec->length () * sizeof (T));
470 /* Free a vector allocated on the stack. Don't actually free it if we
471 find it in the hash table. */
473 template<typename T>
474 void
475 va_stack::release (vec<T, va_stack, vl_embed> *&v)
477 if (v == NULL)
478 return;
480 int ix = stack_vec_register_index (static_cast<void *> (v));
481 if (ix >= 0)
483 unregister_stack_vec (ix);
484 v = NULL;
486 else
488 /* The vector was not on the list of vectors allocated on the stack, so it
489 must be allocated on the heap. */
490 va_heap::release (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v));
495 /* Generic vector template. Default values for A and L indicate the
496 most commonly used strategies.
498 FIXME - Ideally, they would all be vl_ptr to encourage using regular
499 instances for vectors, but the existing GTY machinery is limited
500 in that it can only deal with GC objects that are pointers
501 themselves.
503 This means that vector operations that need to deal with
504 potentially NULL pointers, must be provided as free
505 functions (see the vec_safe_* functions above). */
506 template<typename T,
507 typename A = va_heap,
508 typename L = typename A::default_layout>
509 class GTY((user)) vec
514 /* Embeddable vector. These vectors are suitable to be embedded
515 in other data structures so that they can be pre-allocated in a
516 contiguous memory block.
518 Embeddable vectors are implemented using the trailing array idiom,
519 thus they are not resizeable without changing the address of the
520 vector object itself. This means you cannot have variables or
521 fields of embeddable vector type -- always use a pointer to a
522 vector. The one exception is the final field of a structure, which
523 could be a vector type.
525 You will have to use the embedded_size & embedded_init calls to
526 create such objects, and they will not be resizeable (so the 'safe'
527 allocation variants are not available).
529 Properties:
531 - The whole vector and control data are allocated in a single
532 contiguous block. It uses the trailing-vector idiom, so
533 allocation must reserve enough space for all the elements
534 in the vector plus its control data.
535 - The vector cannot be re-allocated.
536 - The vector cannot grow nor shrink.
537 - No indirections needed for access/manipulation.
538 - It requires 2 words of storage (prior to vector allocation). */
540 template<typename T, typename A>
541 class GTY((user)) vec<T, A, vl_embed>
543 public:
544 unsigned allocated (void) const { return pfx_PRIVATE_.alloc_PRIVATE_; }
545 unsigned length (void) const { return pfx_PRIVATE_.num_PRIVATE_; }
546 bool is_empty (void) const { return pfx_PRIVATE_.num_PRIVATE_ == 0; }
547 T *address (void) { return data_PRIVATE_; }
548 const T *address (void) const { return data_PRIVATE_; }
549 const T &operator[] (unsigned) const;
550 T &operator[] (unsigned);
551 T &last (void);
552 bool space (unsigned) const;
553 bool iterate (unsigned, T *) const;
554 bool iterate (unsigned, T **) const;
555 vec *copy (ALONE_MEM_STAT_DECL) const;
556 void splice (vec &);
557 void splice (vec *src);
558 T *quick_push (const T &);
559 T &pop (void);
560 void truncate (unsigned);
561 void quick_insert (unsigned, const T &);
562 void ordered_remove (unsigned);
563 void unordered_remove (unsigned);
564 void block_remove (unsigned, unsigned);
565 void qsort (int (*) (const void *, const void *));
566 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
567 static size_t embedded_size (unsigned);
568 void embedded_init (unsigned, unsigned = 0);
569 void quick_grow (unsigned len);
570 void quick_grow_cleared (unsigned len);
572 /* vec class can access our internal data and functions. */
573 template <typename, typename, typename> friend class vec;
575 /* The allocator types also need access to our internals. */
576 friend struct va_gc;
577 friend struct va_gc_atomic;
578 friend struct va_heap;
579 friend struct va_stack;
581 /* FIXME - These fields should be private, but we need to cater to
582 compilers that have stricter notions of PODness for types. */
583 vec_prefix pfx_PRIVATE_;
584 T data_PRIVATE_[1];
588 /* Convenience wrapper functions to use when dealing with pointers to
589 embedded vectors. Some functionality for these vectors must be
590 provided via free functions for these reasons:
592 1- The pointer may be NULL (e.g., before initial allocation).
594 2- When the vector needs to grow, it must be reallocated, so
595 the pointer will change its value.
597 Because of limitations with the current GC machinery, all vectors
598 in GC memory *must* be pointers. */
601 /* If V contains no room for NELEMS elements, return false. Otherwise,
602 return true. */
603 template<typename T, typename A>
604 inline bool
605 vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems)
607 return v ? v->space (nelems) : nelems == 0;
611 /* If V is NULL, return 0. Otherwise, return V->length(). */
612 template<typename T, typename A>
613 inline unsigned
614 vec_safe_length (const vec<T, A, vl_embed> *v)
616 return v ? v->length () : 0;
620 /* If V is NULL, return NULL. Otherwise, return V->address(). */
621 template<typename T, typename A>
622 inline T *
623 vec_safe_address (vec<T, A, vl_embed> *v)
625 return v ? v->address () : NULL;
629 /* If V is NULL, return true. Otherwise, return V->is_empty(). */
630 template<typename T, typename A>
631 inline bool
632 vec_safe_is_empty (vec<T, A, vl_embed> *v)
634 return v ? v->is_empty () : true;
638 /* If V does not have space for NELEMS elements, call
639 V->reserve(NELEMS, EXACT). */
640 template<typename T, typename A>
641 inline bool
642 vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false
643 MEM_STAT_DECL)
645 bool extend = nelems ? !vec_safe_space (v, nelems) : false;
646 if (extend)
647 A::reserve (v, nelems, exact PASS_MEM_STAT);
648 return extend;
651 template<typename T, typename A>
652 inline bool
653 vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems MEM_STAT_DECL)
655 return vec_safe_reserve (v, nelems, true PASS_MEM_STAT);
659 /* Allocate GC memory for V with space for NELEMS slots. If NELEMS
660 is 0, V is initialized to NULL. */
662 template<typename T, typename A>
663 inline void
664 vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems MEM_STAT_DECL)
666 v = NULL;
667 vec_safe_reserve (v, nelems);
671 /* Free the GC memory allocated by vector V and set it to NULL. */
673 template<typename T, typename A>
674 inline void
675 vec_free (vec<T, A, vl_embed> *&v)
677 A::release (v);
681 /* Grow V to length LEN. Allocate it, if necessary. */
682 template<typename T, typename A>
683 inline void
684 vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len MEM_STAT_DECL)
686 unsigned oldlen = vec_safe_length (v);
687 gcc_checking_assert (len >= oldlen);
688 vec_safe_reserve_exact (v, len - oldlen PASS_MEM_STAT);
689 v->quick_grow (len PASS_MEM_STAT);
693 /* If V is NULL, allocate it. Call V->safe_grow_cleared(LEN). */
694 template<typename T, typename A>
695 inline void
696 vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len MEM_STAT_DECL)
698 unsigned oldlen = vec_safe_length (v);
699 vec_safe_grow (v, len PASS_MEM_STAT);
700 memset (&(v->address()[oldlen]), 0, sizeof (T) * (len - oldlen));
704 /* If V is NULL return false, otherwise return V->iterate(IX, PTR). */
705 template<typename T, typename A>
706 inline bool
707 vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr)
709 if (v)
710 return v->iterate (ix, ptr);
711 else
713 *ptr = 0;
714 return false;
718 template<typename T, typename A>
719 inline bool
720 vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr)
722 if (v)
723 return v->iterate (ix, ptr);
724 else
726 *ptr = 0;
727 return false;
732 /* If V has no room for one more element, reallocate it. Then call
733 V->quick_push(OBJ). */
734 template<typename T, typename A>
735 inline T *
736 vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj MEM_STAT_DECL)
738 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
739 return v->quick_push (obj PASS_MEM_STAT);
743 /* if V has no room for one more element, reallocate it. Then call
744 V->quick_insert(IX, OBJ). */
745 template<typename T, typename A>
746 inline void
747 vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
748 MEM_STAT_DECL)
750 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
751 v->quick_insert (ix, obj);
755 /* If V is NULL, do nothing. Otherwise, call V->truncate(SIZE). */
756 template<typename T, typename A>
757 inline void
758 vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size)
760 if (v)
761 v->truncate (size);
765 /* If SRC is not NULL, return a pointer to a copy of it. */
766 template<typename T, typename A>
767 inline vec<T, A, vl_embed> *
768 vec_safe_copy (vec<T, A, vl_embed> *src)
770 return src ? src->copy () : NULL;
773 /* Copy the elements from SRC to the end of DST as if by memcpy.
774 Reallocate DST, if necessary. */
775 template<typename T, typename A>
776 inline void
777 vec_safe_splice (vec<T, A, vl_embed> *&dst, vec<T, A, vl_embed> *src
778 MEM_STAT_DECL)
780 unsigned src_len = vec_safe_length (src);
781 if (src_len)
783 vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len);
784 dst->splice (*src);
789 /* Index into vector. Return the IX'th element. IX must be in the
790 domain of the vector. */
792 template<typename T, typename A>
793 inline const T &
794 vec<T, A, vl_embed>::operator[] (unsigned ix) const
796 gcc_checking_assert (ix < pfx_PRIVATE_.num_PRIVATE_);
797 return data_PRIVATE_[ix];
800 template<typename T, typename A>
801 inline T &
802 vec<T, A, vl_embed>::operator[] (unsigned ix)
804 gcc_checking_assert (ix < pfx_PRIVATE_.num_PRIVATE_);
805 return data_PRIVATE_[ix];
809 /* Get the final element of the vector, which must not be empty. */
811 template<typename T, typename A>
812 inline T &
813 vec<T, A, vl_embed>::last (void)
815 gcc_checking_assert (pfx_PRIVATE_.num_PRIVATE_ > 0);
816 return (*this)[pfx_PRIVATE_.num_PRIVATE_ - 1];
820 /* If this vector has space for NELEMS additional entries, return
821 true. You usually only need to use this if you are doing your
822 own vector reallocation, for instance on an embedded vector. This
823 returns true in exactly the same circumstances that vec::reserve
824 will. */
826 template<typename T, typename A>
827 inline bool
828 vec<T, A, vl_embed>::space (unsigned nelems) const
830 return pfx_PRIVATE_.alloc_PRIVATE_ - pfx_PRIVATE_.num_PRIVATE_ >= nelems;
834 /* Return iteration condition and update PTR to point to the IX'th
835 element of this vector. Use this to iterate over the elements of a
836 vector as follows,
838 for (ix = 0; vec<T, A>::iterate(v, ix, &ptr); ix++)
839 continue; */
841 template<typename T, typename A>
842 inline bool
843 vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const
845 if (ix < pfx_PRIVATE_.num_PRIVATE_)
847 *ptr = data_PRIVATE_[ix];
848 return true;
850 else
852 *ptr = 0;
853 return false;
858 /* Return iteration condition and update *PTR to point to the
859 IX'th element of this vector. Use this to iterate over the
860 elements of a vector as follows,
862 for (ix = 0; v->iterate(ix, &ptr); ix++)
863 continue;
865 This variant is for vectors of objects. */
867 template<typename T, typename A>
868 inline bool
869 vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const
871 if (ix < pfx_PRIVATE_.num_PRIVATE_)
873 *ptr = CONST_CAST (T *, &data_PRIVATE_[ix]);
874 return true;
876 else
878 *ptr = 0;
879 return false;
884 /* Return a pointer to a copy of this vector. */
886 template<typename T, typename A>
887 inline vec<T, A, vl_embed> *
888 vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECL) const
890 vec<T, A, vl_embed> *new_vec = NULL;
891 unsigned len = length ();
892 if (len)
894 vec_alloc (new_vec, len PASS_MEM_STAT);
895 new_vec->embedded_init (len, len);
896 memcpy (new_vec->address(), data_PRIVATE_, sizeof (T) * len);
898 return new_vec;
902 /* Copy the elements from SRC to the end of this vector as if by memcpy.
903 The vector must have sufficient headroom available. */
905 template<typename T, typename A>
906 inline void
907 vec<T, A, vl_embed>::splice (vec<T, A, vl_embed> &src)
909 unsigned len = src.length();
910 if (len)
912 gcc_checking_assert (space (len));
913 memcpy (address() + length(), src.address(), len * sizeof (T));
914 pfx_PRIVATE_.num_PRIVATE_ += len;
918 template<typename T, typename A>
919 inline void
920 vec<T, A, vl_embed>::splice (vec<T, A, vl_embed> *src)
922 if (src)
923 splice (*src);
927 /* Push OBJ (a new element) onto the end of the vector. There must be
928 sufficient space in the vector. Return a pointer to the slot
929 where OBJ was inserted. */
931 template<typename T, typename A>
932 inline T *
933 vec<T, A, vl_embed>::quick_push (const T &obj)
935 gcc_checking_assert (space (1));
936 T *slot = &data_PRIVATE_[pfx_PRIVATE_.num_PRIVATE_++];
937 *slot = obj;
938 return slot;
942 /* Pop and return the last element off the end of the vector. */
944 template<typename T, typename A>
945 inline T &
946 vec<T, A, vl_embed>::pop (void)
948 gcc_checking_assert (length () > 0);
949 return data_PRIVATE_[--pfx_PRIVATE_.num_PRIVATE_];
953 /* Set the length of the vector to SIZE. The new length must be less
954 than or equal to the current length. This is an O(1) operation. */
956 template<typename T, typename A>
957 inline void
958 vec<T, A, vl_embed>::truncate (unsigned size)
960 gcc_checking_assert (length () >= size);
961 pfx_PRIVATE_.num_PRIVATE_ = size;
965 /* Insert an element, OBJ, at the IXth position of this vector. There
966 must be sufficient space. */
968 template<typename T, typename A>
969 inline void
970 vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj)
972 gcc_checking_assert (length () < allocated ());
973 gcc_checking_assert (ix <= length ());
974 T *slot = &data_PRIVATE_[ix];
975 memmove (slot + 1, slot, (pfx_PRIVATE_.num_PRIVATE_++ - ix) * sizeof (T));
976 *slot = obj;
980 /* Remove an element from the IXth position of this vector. Ordering of
981 remaining elements is preserved. This is an O(N) operation due to
982 memmove. */
984 template<typename T, typename A>
985 inline void
986 vec<T, A, vl_embed>::ordered_remove (unsigned ix)
988 gcc_checking_assert (ix < length());
989 T *slot = &data_PRIVATE_[ix];
990 memmove (slot, slot + 1, (--pfx_PRIVATE_.num_PRIVATE_ - ix) * sizeof (T));
994 /* Remove an element from the IXth position of this vector. Ordering of
995 remaining elements is destroyed. This is an O(1) operation. */
997 template<typename T, typename A>
998 inline void
999 vec<T, A, vl_embed>::unordered_remove (unsigned ix)
1001 gcc_checking_assert (ix < length());
1002 data_PRIVATE_[ix] = data_PRIVATE_[--pfx_PRIVATE_.num_PRIVATE_];
1006 /* Remove LEN elements starting at the IXth. Ordering is retained.
1007 This is an O(N) operation due to memmove. */
1009 template<typename T, typename A>
1010 inline void
1011 vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len)
1013 gcc_checking_assert (ix + len <= length());
1014 T *slot = &data_PRIVATE_[ix];
1015 pfx_PRIVATE_.num_PRIVATE_ -= len;
1016 memmove (slot, slot + len, (pfx_PRIVATE_.num_PRIVATE_ - ix) * sizeof (T));
1020 /* Sort the contents of this vector with qsort. CMP is the comparison
1021 function to pass to qsort. */
1023 template<typename T, typename A>
1024 inline void
1025 vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))
1027 ::qsort (address(), length(), sizeof (T), cmp);
1031 /* Find and return the first position in which OBJ could be inserted
1032 without changing the ordering of this vector. LESSTHAN is a
1033 function that returns true if the first argument is strictly less
1034 than the second. */
1036 template<typename T, typename A>
1037 unsigned
1038 vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1039 const
1041 unsigned int len = length ();
1042 unsigned int half, middle;
1043 unsigned int first = 0;
1044 while (len > 0)
1046 half = len / 2;
1047 middle = first;
1048 middle += half;
1049 T middle_elem = (*this)[middle];
1050 if (lessthan (middle_elem, obj))
1052 first = middle;
1053 ++first;
1054 len = len - half - 1;
1056 else
1057 len = half;
1059 return first;
1063 /* Return the number of bytes needed to embed an instance of an
1064 embeddable vec inside another data structure.
1066 Use these methods to determine the required size and initialization
1067 of a vector V of type T embedded within another structure (as the
1068 final member):
1070 size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc);
1071 void v->embedded_init(unsigned alloc, unsigned num);
1073 These allow the caller to perform the memory allocation. */
1075 template<typename T, typename A>
1076 inline size_t
1077 vec<T, A, vl_embed>::embedded_size (unsigned alloc)
1079 typedef vec<T, A, vl_embed> vec_embedded;
1080 return offsetof (vec_embedded, data_PRIVATE_) + alloc * sizeof (T);
1084 /* Initialize the vector to contain room for ALLOC elements and
1085 NUM active elements. */
1087 template<typename T, typename A>
1088 inline void
1089 vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num)
1091 pfx_PRIVATE_.alloc_PRIVATE_ = alloc;
1092 pfx_PRIVATE_.num_PRIVATE_ = num;
1096 /* Grow the vector to a specific length. LEN must be as long or longer than
1097 the current length. The new elements are uninitialized. */
1099 template<typename T, typename A>
1100 inline void
1101 vec<T, A, vl_embed>::quick_grow (unsigned len)
1103 gcc_checking_assert (length () <= len && len <= pfx_PRIVATE_.alloc_PRIVATE_);
1104 pfx_PRIVATE_.num_PRIVATE_ = len;
1108 /* Grow the vector to a specific length. LEN must be as long or longer than
1109 the current length. The new elements are initialized to zero. */
1111 template<typename T, typename A>
1112 inline void
1113 vec<T, A, vl_embed>::quick_grow_cleared (unsigned len)
1115 unsigned oldlen = length ();
1116 quick_grow (len);
1117 memset (&(address()[oldlen]), 0, sizeof (T) * (len - oldlen));
1121 /* Garbage collection support for vec<T, A, vl_embed>. */
1123 template<typename T>
1124 void
1125 gt_ggc_mx (vec<T, va_gc> *v)
1127 extern void gt_ggc_mx (T &);
1128 for (unsigned i = 0; i < v->length (); i++)
1129 gt_ggc_mx ((*v)[i]);
1132 template<typename T>
1133 void
1134 gt_ggc_mx (vec<T, va_gc_atomic, vl_embed> *v ATTRIBUTE_UNUSED)
1136 /* Nothing to do. Vectors of atomic types wrt GC do not need to
1137 be traversed. */
1141 /* PCH support for vec<T, A, vl_embed>. */
1143 template<typename T, typename A>
1144 void
1145 gt_pch_nx (vec<T, A, vl_embed> *v)
1147 extern void gt_pch_nx (T &);
1148 for (unsigned i = 0; i < v->length (); i++)
1149 gt_pch_nx ((*v)[i]);
1152 template<typename T, typename A>
1153 void
1154 gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1156 for (unsigned i = 0; i < v->length (); i++)
1157 op (&((*v)[i]), cookie);
1160 template<typename T, typename A>
1161 void
1162 gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1164 extern void gt_pch_nx (T *, gt_pointer_operator, void *);
1165 for (unsigned i = 0; i < v->length (); i++)
1166 gt_pch_nx (&((*v)[i]), op, cookie);
1170 /* Space efficient vector. These vectors can grow dynamically and are
1171 allocated together with their control data. They are suited to be
1172 included in data structures. Prior to initial allocation, they
1173 only take a single word of storage.
1175 These vectors are implemented as a pointer to an embeddable vector.
1176 The semantics allow for this pointer to be NULL to represent empty
1177 vectors. This way, empty vectors occupy minimal space in the
1178 structure containing them.
1180 Properties:
1182 - The whole vector and control data are allocated in a single
1183 contiguous block.
1184 - The whole vector may be re-allocated.
1185 - Vector data may grow and shrink.
1186 - Access and manipulation requires a pointer test and
1187 indirection.
1188 - It requires 1 word of storage (prior to vector allocation).
1191 Limitations:
1193 These vectors must be PODs because they are stored in unions.
1194 (http://en.wikipedia.org/wiki/Plain_old_data_structures).
1195 As long as we use C++03, we cannot have constructors nor
1196 destructors in classes that are stored in unions. */
1198 template<typename T, typename A>
1199 class vec<T, A, vl_ptr>
1201 public:
1202 /* Memory allocation and deallocation for the embedded vector.
1203 Needed because we cannot have proper ctors/dtors defined. */
1204 void create (unsigned nelems CXX_MEM_STAT_INFO);
1205 void release (void);
1207 /* Vector operations. */
1208 bool exists (void) const
1209 { return vec_PRIVATE_ != NULL; }
1211 bool is_empty (void) const
1212 { return vec_PRIVATE_ ? vec_PRIVATE_->is_empty() : true; }
1214 unsigned length (void) const
1215 { return vec_PRIVATE_ ? vec_PRIVATE_->length() : 0; }
1217 T *address (void)
1218 { return vec_PRIVATE_ ? vec_PRIVATE_->data_PRIVATE_ : NULL; }
1220 const T *address (void) const
1221 { return vec_PRIVATE_ ? vec_PRIVATE_->data_PRIVATE_ : NULL; }
1223 const T &operator[] (unsigned ix) const
1224 { return (*vec_PRIVATE_)[ix]; }
1226 bool operator!=(const vec &other) const
1227 { return !(*this == other); }
1229 bool operator==(const vec &other) const
1230 { return address() == other.address(); }
1232 T &operator[] (unsigned ix)
1233 { return (*vec_PRIVATE_)[ix]; }
1235 T &last (void)
1236 { return vec_PRIVATE_->last(); }
1238 bool space (int nelems) const
1239 { return vec_PRIVATE_ ? vec_PRIVATE_->space (nelems) : nelems == 0; }
1241 bool iterate (unsigned ix, T *p) const;
1242 bool iterate (unsigned ix, T **p) const;
1243 vec copy (ALONE_CXX_MEM_STAT_INFO) const;
1244 bool reserve (unsigned, bool = false CXX_MEM_STAT_INFO);
1245 bool reserve_exact (unsigned CXX_MEM_STAT_INFO);
1246 void splice (vec &);
1247 void safe_splice (vec & CXX_MEM_STAT_INFO);
1248 T *quick_push (const T &);
1249 T *safe_push (const T &CXX_MEM_STAT_INFO);
1250 T &pop (void);
1251 void truncate (unsigned);
1252 void safe_grow (unsigned CXX_MEM_STAT_INFO);
1253 void safe_grow_cleared (unsigned CXX_MEM_STAT_INFO);
1254 void quick_grow (unsigned);
1255 void quick_grow_cleared (unsigned);
1256 void quick_insert (unsigned, const T &);
1257 void safe_insert (unsigned, const T & CXX_MEM_STAT_INFO);
1258 void ordered_remove (unsigned);
1259 void unordered_remove (unsigned);
1260 void block_remove (unsigned, unsigned);
1261 void qsort (int (*) (const void *, const void *));
1262 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
1264 template<typename T1>
1265 friend void va_stack::alloc(vec<T1, va_stack, vl_ptr>&, unsigned,
1266 vec<T1, va_stack, vl_embed> *);
1268 /* FIXME - This field should be private, but we need to cater to
1269 compilers that have stricter notions of PODness for types. */
1270 vec<T, A, vl_embed> *vec_PRIVATE_;
1274 /* Empty specialization for GC allocation. This will prevent GC
1275 vectors from using the vl_ptr layout. FIXME: This is needed to
1276 circumvent limitations in the GTY machinery. */
1278 template<typename T>
1279 class vec<T, va_gc, vl_ptr>
1284 /* Allocate heap memory for pointer V and create the internal vector
1285 with space for NELEMS elements. If NELEMS is 0, the internal
1286 vector is initialized to empty. */
1288 template<typename T>
1289 inline void
1290 vec_alloc (vec<T> *&v, unsigned nelems MEM_STAT_DECL)
1292 v = new vec<T>;
1293 v->create (nelems PASS_MEM_STAT);
1297 /* Conditionally allocate heap memory for VEC and its internal vector. */
1299 template<typename T>
1300 inline void
1301 vec_check_alloc (vec<T, va_heap> *&vec, unsigned nelems MEM_STAT_DECL)
1303 if (!vec)
1304 vec_alloc (vec, nelems PASS_MEM_STAT);
1308 /* Free the heap memory allocated by vector V and set it to NULL. */
1310 template<typename T>
1311 inline void
1312 vec_free (vec<T> *&v)
1314 if (v == NULL)
1315 return;
1317 v->release ();
1318 delete v;
1319 v = NULL;
1323 /* Allocate a new stack vector with space for exactly NELEMS objects.
1324 If NELEMS is zero, NO vector is created.
1326 For the stack allocator, no memory is really allocated. The vector
1327 is initialized to be at address SPACE and contain NELEMS slots.
1328 Memory allocation actually occurs in the expansion of VEC_alloc.
1330 Usage notes:
1332 * This does not allocate an instance of vec<T, A>. It allocates the
1333 actual vector of elements (i.e., vec<T, A, vl_embed>) inside a
1334 vec<T, A> instance.
1336 * This allocator must always be a macro:
1338 We support a vector which starts out with space on the stack and
1339 switches to heap space when forced to reallocate. This works a
1340 little differently. In the case of stack vectors, vec_alloc will
1341 expand to a call to vec_alloc_1 that calls XALLOCAVAR to request
1342 the initial allocation. This uses alloca to get the initial
1343 space. Since alloca can not be usefully called in an inline
1344 function, vec_alloc must always be a macro.
1346 Important limitations of stack vectors:
1348 - Only the initial allocation will be made using alloca, so pass
1349 a reasonable estimate that doesn't use too much stack space;
1350 don't pass zero.
1352 - Don't return a stack-allocated vector from the function which
1353 allocated it. */
1355 #define vec_stack_alloc(T,V,N) \
1356 do { \
1357 typedef vec<T, va_stack, vl_embed> stackv; \
1358 va_stack::alloc (V, N, XALLOCAVAR (stackv, stackv::embedded_size (N)));\
1359 } while (0)
1362 /* Return iteration condition and update PTR to point to the IX'th
1363 element of this vector. Use this to iterate over the elements of a
1364 vector as follows,
1366 for (ix = 0; v.iterate(ix, &ptr); ix++)
1367 continue; */
1369 template<typename T, typename A>
1370 inline bool
1371 vec<T, A, vl_ptr>::iterate (unsigned ix, T *ptr) const
1373 if (vec_PRIVATE_)
1374 return vec_PRIVATE_->iterate (ix, ptr);
1375 else
1377 *ptr = 0;
1378 return false;
1383 /* Return iteration condition and update *PTR to point to the
1384 IX'th element of this vector. Use this to iterate over the
1385 elements of a vector as follows,
1387 for (ix = 0; v->iterate(ix, &ptr); ix++)
1388 continue;
1390 This variant is for vectors of objects. */
1392 template<typename T, typename A>
1393 inline bool
1394 vec<T, A, vl_ptr>::iterate (unsigned ix, T **ptr) const
1396 if (vec_PRIVATE_)
1397 return vec_PRIVATE_->iterate (ix, ptr);
1398 else
1400 *ptr = 0;
1401 return false;
1406 /* Convenience macro for forward iteration. */
1407 #define FOR_EACH_VEC_ELT(V, I, P) \
1408 for (I = 0; (V).iterate ((I), &(P)); ++(I))
1410 #define FOR_EACH_VEC_SAFE_ELT(V, I, P) \
1411 for (I = 0; vec_safe_iterate ((V), (I), &(P)); ++(I))
1413 /* Likewise, but start from FROM rather than 0. */
1414 #define FOR_EACH_VEC_ELT_FROM(V, I, P, FROM) \
1415 for (I = (FROM); (V).iterate ((I), &(P)); ++(I))
1417 /* Convenience macro for reverse iteration. */
1418 #define FOR_EACH_VEC_ELT_REVERSE(V, I, P) \
1419 for (I = (V).length () - 1; \
1420 (V).iterate ((I), &(P)); \
1421 (I)--)
1423 #define FOR_EACH_VEC_SAFE_ELT_REVERSE(V, I, P) \
1424 for (I = vec_safe_length (V) - 1; \
1425 vec_safe_iterate ((V), (I), &(P)); \
1426 (I)--)
1429 /* Return a copy of this vector. */
1431 template<typename T, typename A>
1432 inline vec<T, A, vl_ptr>
1433 vec<T, A, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
1435 vec<T, A, vl_ptr> new_vec = vec<T, A, vl_ptr>();
1436 if (length ())
1437 new_vec.vec_PRIVATE_ = vec_PRIVATE_->copy ();
1438 return new_vec;
1442 /* Ensure that the vector has at least RESERVE slots available (if
1443 EXACT is false), or exactly RESERVE slots available (if EXACT is
1444 true).
1446 This may create additional headroom if EXACT is false.
1448 Note that this can cause the embedded vector to be reallocated.
1449 Returns true iff reallocation actually occurred. */
1451 template<typename T, typename A>
1452 inline bool
1453 vec<T, A, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
1455 bool extend = nelems ? !space (nelems) : false;
1456 if (extend)
1457 A::reserve (vec_PRIVATE_, nelems, exact PASS_MEM_STAT);
1458 return extend;
1462 /* Ensure that this vector has exactly NELEMS slots available. This
1463 will not create additional headroom. Note this can cause the
1464 embedded vector to be reallocated. Returns true iff reallocation
1465 actually occurred. */
1467 template<typename T, typename A>
1468 inline bool
1469 vec<T, A, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
1471 return reserve (nelems, true PASS_MEM_STAT);
1475 /* Create the internal vector and reserve NELEMS for it. This is
1476 exactly like vec::reserve, but the internal vector is
1477 unconditionally allocated from scratch. The old one, if it
1478 existed, is lost. */
1480 template<typename T, typename A>
1481 inline void
1482 vec<T, A, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
1484 vec_PRIVATE_ = NULL;
1485 if (nelems > 0)
1486 reserve_exact (nelems PASS_MEM_STAT);
1490 /* Free the memory occupied by the embedded vector. */
1492 template<typename T, typename A>
1493 inline void
1494 vec<T, A, vl_ptr>::release (void)
1496 if (vec_PRIVATE_)
1497 A::release (vec_PRIVATE_);
1501 /* Copy the elements from SRC to the end of this vector as if by memcpy.
1502 SRC and this vector must be allocated with the same memory
1503 allocation mechanism. This vector is assumed to have sufficient
1504 headroom available. */
1506 template<typename T, typename A>
1507 inline void
1508 vec<T, A, vl_ptr>::splice (vec<T, A, vl_ptr> &src)
1510 if (src.vec_PRIVATE_)
1511 vec_PRIVATE_->splice (*(src.vec_PRIVATE_));
1515 /* Copy the elements in SRC to the end of this vector as if by memcpy.
1516 SRC and this vector must be allocated with the same mechanism.
1517 If there is not enough headroom in this vector, it will be reallocated
1518 as needed. */
1520 template<typename T, typename A>
1521 inline void
1522 vec<T, A, vl_ptr>::safe_splice (vec<T, A, vl_ptr> &src MEM_STAT_DECL)
1524 if (src.length())
1526 reserve_exact (src.length());
1527 splice (src);
1532 /* Push OBJ (a new element) onto the end of the vector. There must be
1533 sufficient space in the vector. Return a pointer to the slot
1534 where OBJ was inserted. */
1536 template<typename T, typename A>
1537 inline T *
1538 vec<T, A, vl_ptr>::quick_push (const T &obj)
1540 return vec_PRIVATE_->quick_push (obj);
1544 /* Push a new element OBJ onto the end of this vector. Reallocates
1545 the embedded vector, if needed. Return a pointer to the slot where
1546 OBJ was inserted. */
1548 template<typename T, typename A>
1549 inline T *
1550 vec<T, A, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
1552 reserve (1, false PASS_MEM_STAT);
1553 return quick_push (obj);
1557 /* Pop and return the last element off the end of the vector. */
1559 template<typename T, typename A>
1560 inline T &
1561 vec<T, A, vl_ptr>::pop (void)
1563 return vec_PRIVATE_->pop ();
1567 /* Set the length of the vector to LEN. The new length must be less
1568 than or equal to the current length. This is an O(1) operation. */
1570 template<typename T, typename A>
1571 inline void
1572 vec<T, A, vl_ptr>::truncate (unsigned size)
1574 if (vec_PRIVATE_)
1575 vec_PRIVATE_->truncate (size);
1576 else
1577 gcc_checking_assert (size == 0);
1581 /* Grow the vector to a specific length. LEN must be as long or
1582 longer than the current length. The new elements are
1583 uninitialized. Reallocate the internal vector, if needed. */
1585 template<typename T, typename A>
1586 inline void
1587 vec<T, A, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
1589 unsigned oldlen = length ();
1590 gcc_checking_assert (oldlen <= len);
1591 reserve_exact (len - oldlen PASS_MEM_STAT);
1592 vec_PRIVATE_->quick_grow (len);
1596 /* Grow the embedded vector to a specific length. LEN must be as
1597 long or longer than the current length. The new elements are
1598 initialized to zero. Reallocate the internal vector, if needed. */
1600 template<typename T, typename A>
1601 inline void
1602 vec<T, A, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
1604 unsigned oldlen = length ();
1605 safe_grow (len PASS_MEM_STAT);
1606 memset (&(address()[oldlen]), 0, sizeof (T) * (len - oldlen));
1610 /* Same as vec::safe_grow but without reallocation of the internal vector.
1611 If the vector cannot be extended, a runtime assertion will be triggered. */
1613 template<typename T, typename A>
1614 inline void
1615 vec<T, A, vl_ptr>::quick_grow (unsigned len)
1617 gcc_checking_assert (vec_PRIVATE_);
1618 vec_PRIVATE_->quick_grow (len);
1622 /* Same as vec::quick_grow_cleared but without reallocation of the
1623 internal vector. If the vector cannot be extended, a runtime
1624 assertion will be triggered. */
1626 template<typename T, typename A>
1627 inline void
1628 vec<T, A, vl_ptr>::quick_grow_cleared (unsigned len)
1630 gcc_checking_assert (vec_PRIVATE_);
1631 vec_PRIVATE_->quick_grow_cleared (len);
1635 /* Insert an element, OBJ, at the IXth position of this vector. There
1636 must be sufficient space. */
1638 template<typename T, typename A>
1639 inline void
1640 vec<T, A, vl_ptr>::quick_insert (unsigned ix, const T &obj)
1642 vec_PRIVATE_->quick_insert (ix, obj);
1646 /* Insert an element, OBJ, at the IXth position of the vector.
1647 Reallocate the embedded vector, if necessary. */
1649 template<typename T, typename A>
1650 inline void
1651 vec<T, A, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
1653 reserve (1, false PASS_MEM_STAT);
1654 quick_insert (ix, obj);
1658 /* Remove an element from the IXth position of this vector. Ordering of
1659 remaining elements is preserved. This is an O(N) operation due to
1660 a memmove. */
1662 template<typename T, typename A>
1663 inline void
1664 vec<T, A, vl_ptr>::ordered_remove (unsigned ix)
1666 vec_PRIVATE_->ordered_remove (ix);
1670 /* Remove an element from the IXth position of this vector. Ordering
1671 of remaining elements is destroyed. This is an O(1) operation. */
1673 template<typename T, typename A>
1674 inline void
1675 vec<T, A, vl_ptr>::unordered_remove (unsigned ix)
1677 vec_PRIVATE_->unordered_remove (ix);
1681 /* Remove LEN elements starting at the IXth. Ordering is retained.
1682 This is an O(N) operation due to memmove. */
1684 template<typename T, typename A>
1685 inline void
1686 vec<T, A, vl_ptr>::block_remove (unsigned ix, unsigned len)
1688 vec_PRIVATE_->block_remove (ix, len);
1692 /* Sort the contents of this vector with qsort. CMP is the comparison
1693 function to pass to qsort. */
1695 template<typename T, typename A>
1696 inline void
1697 vec<T, A, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
1699 if (vec_PRIVATE_)
1700 vec_PRIVATE_->qsort (cmp);
1704 /* Find and return the first position in which OBJ could be inserted
1705 without changing the ordering of this vector. LESSTHAN is a
1706 function that returns true if the first argument is strictly less
1707 than the second. */
1709 template<typename T, typename A>
1710 inline unsigned
1711 vec<T, A, vl_ptr>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1712 const
1714 return vec_PRIVATE_ ? vec_PRIVATE_->lower_bound (obj, lessthan) : 0;
1717 #endif // GCC_VEC_H