]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/vec.h
This patch rewrites the old VEC macro-based interface into a new one
[thirdparty/gcc.git] / gcc / vec.h
CommitLineData
190183c5 1/* Vector API for GNU compiler.
2b15d2ba 2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
73685692 3 Free Software Foundation, Inc.
190183c5 4 Contributed by Nathan Sidwell <nathan@codesourcery.com>
2b15d2ba 5 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
190183c5 6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
8c4c00c1 11Software Foundation; either version 3, or (at your option) any later
190183c5 12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
8c4c00c1 20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
190183c5 22
23#ifndef GCC_VEC_H
24#define GCC_VEC_H
25
f1f41a6c 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.
30
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
41
42#include "statistics.h" // For CXX_MEM_STAT_INFO.
43
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
ea269688 59
de2b4872 60/* Templated vector type and associated interfaces.
61
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.
65
de2b4872 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.
930bdacf 71
190183c5 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
1fa3a8f6 75 (it dies if there is not). The latter will reallocate the
190183c5 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
046bfc77 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
24ffec38 83 (for instance, you know this is the last allocation), use the
84 reserve_exact operation. You can also create a vector of a
046bfc77 85 specific size from the get go.
190183c5 86
87 You should prefer the push and pop operations, as they append and
15f5ee9f 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
190183c5 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
046bfc77 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
145fce5e 96 array using insert that will maintain sorted order.
930bdacf 97
f1f41a6c 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
101
102 Four allocation strategies are supported:
103
104 - Heap: allocation is done using malloc/free. This is the
105 default allocation strategy.
106
107 - Stack: allocation is done using alloca.
108
109 - GC: allocation is done using ggc_alloc/ggc_free.
110
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.
117
118 Two physical layouts are supported:
119
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).
126
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).
133
134 The type, allocation and layout are specified when the vector is
135 declared.
48e1416a 136
930bdacf 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.
48e1416a 141
f1f41a6c 142 Notes on the different layout strategies
143
144 * Embeddable vectors (vec<T, A, vl_embed>)
145
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.
149
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.
156
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).
160
161 Properties of embeddable vectors:
162
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).
171
172
173 * Space efficient vector (vec<T, A, vl_ptr>)
174
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.
179
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.
184
185 Properties:
186
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).
190183c5 194
195 An example of their use would be,
196
190183c5 197 struct my_struct {
f1f41a6c 198 // A space-efficient vector of tree pointers in GC memory.
199 vec<tree, va_gc, vl_ptr> v;
190183c5 200 };
201
202 struct my_struct *s;
203
f1f41a6c 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++)
6c798041 207 { do something with elt }
190183c5 208*/
209
f1f41a6c 210/* Support function for statistics. */
211extern void dump_vec_loc_statistics (void);
2b15d2ba 212
2b15d2ba 213
f1f41a6c 214/* Control data for vectors. This contains the number of allocated
215 and used slots inside a vector. */
2b15d2ba 216
f1f41a6c 217class vec_prefix
2b15d2ba 218{
f1f41a6c 219protected:
220 /* Memory allocation support routines in vec.c. */
221 void register_overhead (size_t, const char *, int, const char *);
222 void release_overhead (void);
223 static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
224
225 /* Note that vec_prefix should be a base class for vec, but we use
226 offsetof() on vector fields of tree structures (e.g.,
227 tree_binfo::base_binfos), and offsetof only supports base types.
228
229 To compensate, we make vec_prefix a field inside vec and make
230 vec a friend class of vec_prefix so it can access its fields. */
231 template <typename, typename, typename> friend class vec;
232
233 /* The allocator types also need access to our internals. */
234 friend struct va_gc;
235 friend struct va_gc_atomic;
236 friend struct va_heap;
237 friend struct va_stack;
238
de2b4872 239 unsigned alloc_;
f1f41a6c 240 unsigned num_;
2b15d2ba 241};
242
f1f41a6c 243template<typename, typename, typename> class vec;
de2b4872 244
f1f41a6c 245/* Valid vector layouts
de2b4872 246
f1f41a6c 247 vl_embed - Embeddable vector that uses the trailing array idiom.
248 vl_ptr - Space efficient vector that uses a pointer to an
249 embeddable vector. */
250struct vl_embed { };
251struct vl_ptr { };
de2b4872 252
de2b4872 253
f1f41a6c 254/* Types of supported allocations
de2b4872 255
f1f41a6c 256 va_heap - Allocation uses malloc/free.
257 va_gc - Allocation uses ggc_alloc.
258 va_gc_atomic - Same as GC, but individual elements of the array
259 do not need to be marked during collection.
260 va_stack - Allocation uses alloca. */
de2b4872 261
f1f41a6c 262/* Allocator type for heap vectors. */
263struct va_heap
264{
265 /* Heap vectors are frequently regular instances, so use the vl_ptr
266 layout for them. */
267 typedef vl_ptr default_layout;
de2b4872 268
f1f41a6c 269 template<typename T>
270 static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool
271 CXX_MEM_STAT_INFO);
de2b4872 272
f1f41a6c 273 template<typename T>
274 static void release (vec<T, va_heap, vl_embed> *&);
275};
de2b4872 276
de2b4872 277
f1f41a6c 278/* Allocator for heap memory. Ensure there are at least RESERVE free
279 slots in V. If EXACT is true, grow exactly, else grow
280 exponentially. As a special case, if the vector had not been
281 allocated and and RESERVE is 0, no vector will be created. */
de2b4872 282
f1f41a6c 283template<typename T>
284inline void
285va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
286 MEM_STAT_DECL)
287{
288 unsigned alloc = vec_prefix::calculate_allocation (v ? &v->pfx_ : 0, reserve,
289 exact);
290 if (!alloc)
291 {
292 release (v);
293 return;
294 }
de2b4872 295
f1f41a6c 296 if (GATHER_STATISTICS && v)
297 v->pfx_.release_overhead ();
de2b4872 298
f1f41a6c 299 size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
300 unsigned nelem = v ? v->length () : 0;
301 v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size));
302 v->embedded_init (alloc, nelem);
de2b4872 303
f1f41a6c 304 if (GATHER_STATISTICS)
305 v->pfx_.register_overhead (size FINAL_PASS_MEM_STAT);
306}
2b15d2ba 307
de2b4872 308
f1f41a6c 309/* Free the heap space allocated for vector V. */
2b15d2ba 310
311template<typename T>
312void
f1f41a6c 313va_heap::release (vec<T, va_heap, vl_embed> *&v)
2b15d2ba 314{
f1f41a6c 315 if (GATHER_STATISTICS)
316 v->pfx_.release_overhead ();
317 ::free (v);
318 v = NULL;
2b15d2ba 319}
320
321
f1f41a6c 322/* Allocator type for GC vectors. Notice that we need the structure
323 declaration even if GC is not enabled. */
2b15d2ba 324
f1f41a6c 325struct va_gc
2b15d2ba 326{
f1f41a6c 327 /* Use vl_embed as the default layout for GC vectors. Due to GTY
328 limitations, GC vectors must always be pointers, so it is more
329 efficient to use a pointer to the vl_embed layout, rather than
330 using a pointer to a pointer as would be the case with vl_ptr. */
331 typedef vl_embed default_layout;
332
333 template<typename T, typename A>
334 static void reserve (vec<T, A, vl_embed> *&, unsigned, bool
335 CXX_MEM_STAT_INFO);
336
337 template<typename T, typename A>
338 static void release (vec<T, A, vl_embed> *&v) { v = NULL; }
339};
2b15d2ba 340
2b15d2ba 341
f1f41a6c 342/* Allocator for GC memory. Ensure there are at least RESERVE free
343 slots in V. If EXACT is true, grow exactly, else grow
344 exponentially. As a special case, if the vector had not been
345 allocated and and RESERVE is 0, no vector will be created. */
346
347template<typename T, typename A>
2b15d2ba 348void
f1f41a6c 349va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
350 MEM_STAT_DECL)
2b15d2ba 351{
f1f41a6c 352 unsigned alloc = vec_prefix::calculate_allocation (v ? &v->pfx_ : 0, reserve,
353 exact);
354 if (!alloc)
355 {
356 ::ggc_free (v);
357 v = NULL;
358 return;
359 }
2b15d2ba 360
f1f41a6c 361 /* Calculate the amount of space we want. */
362 size_t size = vec<T, A, vl_embed>::embedded_size (alloc);
2b15d2ba 363
f1f41a6c 364 /* Ask the allocator how much space it will really give us. */
365 size = ggc_round_alloc_size (size);
2b15d2ba 366
f1f41a6c 367 /* Adjust the number of slots accordingly. */
368 size_t vec_offset = sizeof (vec_prefix);
369 size_t elt_size = sizeof (T);
370 alloc = (size - vec_offset) / elt_size;
2b15d2ba 371
f1f41a6c 372 /* And finally, recalculate the amount of space we ask for. */
373 size = vec_offset + alloc * elt_size;
2b15d2ba 374
f1f41a6c 375 unsigned nelem = v ? v->length () : 0;
376 v = static_cast <vec<T, A, vl_embed> *> (ggc_realloc_stat (v, size));
377 v->embedded_init (alloc, nelem);
378}
190183c5 379
190183c5 380
f1f41a6c 381/* Allocator type for GC vectors. This is for vectors of types
382 atomics w.r.t. collection, so allocation and deallocation is
383 completely inherited from va_gc. */
384struct va_gc_atomic : va_gc
385{
386};
930bdacf 387
2b15d2ba 388
f1f41a6c 389/* Allocator type for stack vectors. */
390struct va_stack
2b15d2ba 391{
f1f41a6c 392 /* Use vl_ptr as the default layout for stack vectors. */
393 typedef vl_ptr default_layout;
190183c5 394
f1f41a6c 395 template<typename T>
396 static void alloc (vec<T, va_stack, vl_ptr>&, unsigned,
397 vec<T, va_stack, vl_embed> *);
c75b4594 398
f1f41a6c 399 template <typename T>
400 static void reserve (vec<T, va_stack, vl_embed> *&, unsigned, bool
401 CXX_MEM_STAT_INFO);
c75b4594 402
f1f41a6c 403 template <typename T>
404 static void release (vec<T, va_stack, vl_embed> *&);
405};
406
407/* Helper functions to keep track of vectors allocated on the stack. */
408void register_stack_vec (void *);
409int stack_vec_register_index (void *);
410void unregister_stack_vec (unsigned);
c75b4594 411
f1f41a6c 412/* Allocate a vector V which uses alloca for the initial allocation.
413 SPACE is space allocated using alloca. NELEMS is the number of
414 entries allocated. */
415
416template<typename T>
417void
418va_stack::alloc (vec<T, va_stack, vl_ptr> &v, unsigned nelems,
419 vec<T, va_stack, vl_embed> *space)
420{
421 v.vec_ = space;
422 register_stack_vec (static_cast<void *> (v.vec_));
423 v.vec_->embedded_init (nelems, 0);
424}
2b15d2ba 425
de2b4872 426
f1f41a6c 427/* Reserve NELEMS slots for a vector initially allocated on the stack.
428 When this happens, we switch back to heap allocation. We remove
429 the vector from stack_vecs, if it is there, since we no longer need
430 to avoid freeing it. If EXACT is true, grow exactly, otherwise
431 grow exponentially. */
de2b4872 432
f1f41a6c 433template<typename T>
434void
435va_stack::reserve (vec<T, va_stack, vl_embed> *&v, unsigned nelems, bool exact
436 MEM_STAT_DECL)
437{
438 int ix = stack_vec_register_index (static_cast<void *> (v));
439 if (ix >= 0)
440 unregister_stack_vec (ix);
441 else
442 {
443 /* V is already on the heap. */
444 va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v),
445 nelems, exact);
446 return;
447 }
de2b4872 448
f1f41a6c 449 /* Move VEC_ to the heap. */
450 nelems += v->pfx_.num_;
451 vec<T, va_stack, vl_embed> *oldvec = v;
452 v = NULL;
453 va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&>(v), nelems,
454 exact);
455 if (v && oldvec)
456 {
457 v->pfx_.num_ = oldvec->length ();
458 memcpy (v->data_, oldvec->data_, oldvec->length () * sizeof (T));
459 }
460}
de2b4872 461
de2b4872 462
f1f41a6c 463/* Free a vector allocated on the stack. Don't actually free it if we
464 find it in the hash table. */
de2b4872 465
f1f41a6c 466template<typename T>
467void
468va_stack::release (vec<T, va_stack, vl_embed> *&v)
469{
470 int ix = stack_vec_register_index (static_cast<void *> (v));
471 if (ix >= 0)
472 {
473 unregister_stack_vec (ix);
474 v = NULL;
475 }
476 else
477 {
478 /* The vector was not on the list of vectors allocated on the stack, so it
479 must be allocated on the heap. */
480 va_heap::release (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v));
481 }
482}
de2b4872 483
de2b4872 484
f1f41a6c 485/* Generic vector template. Default values for A and L indicate the
486 most commonly used strategies.
de2b4872 487
f1f41a6c 488 FIXME - Ideally, they would all be vl_ptr to encourage using regular
489 instances for vectors, but the existing GTY machinery is limited
490 in that it can only deal with GC objects that are pointers
491 themselves.
de2b4872 492
f1f41a6c 493 This means that vector operations that need to deal with
494 potentially NULL pointers, must be provided as free
495 functions (see the vec_safe_* functions above). */
496template<typename T,
497 typename A = va_heap,
498 typename L = typename A::default_layout>
499class GTY((user)) vec
500{
501};
de2b4872 502
de2b4872 503
f1f41a6c 504/* Embeddable vector. These vectors are suitable to be embedded
505 in other data structures so that they can be pre-allocated in a
506 contiguous memory block.
de2b4872 507
f1f41a6c 508 Embeddable vectors are implemented using the trailing array idiom,
509 thus they are not resizeable without changing the address of the
510 vector object itself. This means you cannot have variables or
511 fields of embeddable vector type -- always use a pointer to a
512 vector. The one exception is the final field of a structure, which
513 could be a vector type.
de2b4872 514
f1f41a6c 515 You will have to use the embedded_size & embedded_init calls to
516 create such objects, and they will not be resizeable (so the 'safe'
517 allocation variants are not available).
518
519 Properties:
520
521 - The whole vector and control data are allocated in a single
522 contiguous block. It uses the trailing-vector idiom, so
523 allocation must reserve enough space for all the elements
524 in the vector plus its control data.
525 - The vector cannot be re-allocated.
526 - The vector cannot grow nor shrink.
527 - No indirections needed for access/manipulation.
528 - It requires 2 words of storage (prior to vector allocation). */
529
530template<typename T, typename A>
531class GTY((user)) vec<T, A, vl_embed>
532{
533public:
534 unsigned allocated (void) const { return pfx_.alloc_; }
535 unsigned length (void) const { return pfx_.num_; }
536 bool is_empty (void) const { return pfx_.num_ == 0; }
537 T *address (void) { return data_; }
538 const T *address (void) const { return data_; }
539 const T &operator[] (unsigned) const;
540 T &operator[] (unsigned);
541 T &last (void);
542 bool space (unsigned) const;
543 bool iterate (unsigned, T *) const;
544 bool iterate (unsigned, T **) const;
545 vec *copy (ALONE_MEM_STAT_DECL) const;
546 void splice (vec &);
547 void splice (vec *src);
548 T *quick_push (const T &);
549 T &pop (void);
550 void truncate (unsigned);
551 void quick_insert (unsigned, const T &);
552 void ordered_remove (unsigned);
553 void unordered_remove (unsigned);
554 void block_remove (unsigned, unsigned);
555 void qsort (int (*) (const void *, const void *));
556 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
557 static size_t embedded_size (unsigned);
558 void embedded_init (unsigned, unsigned = 0);
559 void quick_grow (unsigned len);
560 void quick_grow_cleared (unsigned len);
561
562 /* vec class can access our internal data and functions. */
563 template <typename, typename, typename> friend class vec;
564
565 /* The allocator types also need access to our internals. */
566 friend struct va_gc;
567 friend struct va_gc_atomic;
568 friend struct va_heap;
569 friend struct va_stack;
570
571private:
572 vec_prefix pfx_;
573 T data_[1];
574};
de2b4872 575
de2b4872 576
f1f41a6c 577/* Convenience wrapper functions to use when dealing with pointers to
578 embedded vectors. Some functionality for these vectors must be
579 provided via free functions for these reasons:
2b15d2ba 580
f1f41a6c 581 1- The pointer may be NULL (e.g., before initial allocation).
2b15d2ba 582
f1f41a6c 583 2- When the vector needs to grow, it must be reallocated, so
584 the pointer will change its value.
2b15d2ba 585
f1f41a6c 586 Because of limitations with the current GC machinery, all vectors
587 in GC memory *must* be pointers. */
2b15d2ba 588
de2b4872 589
f1f41a6c 590/* If V contains no room for NELEMS elements, return false. Otherwise,
591 return true. */
592template<typename T, typename A>
593inline bool
594vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems)
595{
596 return v ? v->space (nelems) : nelems == 0;
597}
de2b4872 598
2b15d2ba 599
f1f41a6c 600/* If V is NULL, return 0. Otherwise, return V->length(). */
601template<typename T, typename A>
de2b4872 602inline unsigned
f1f41a6c 603vec_safe_length (const vec<T, A, vl_embed> *v)
2b15d2ba 604{
f1f41a6c 605 return v ? v->length () : 0;
2b15d2ba 606}
c75b4594 607
608
f1f41a6c 609/* If V is NULL, return NULL. Otherwise, return V->address(). */
610template<typename T, typename A>
611inline T *
612vec_safe_address (vec<T, A, vl_embed> *v)
613{
614 return v ? v->address () : NULL;
615}
616
de2b4872 617
f1f41a6c 618/* If V is NULL, return true. Otherwise, return V->is_empty(). */
619template<typename T, typename A>
de2b4872 620inline bool
f1f41a6c 621vec_safe_is_empty (vec<T, A, vl_embed> *v)
de2b4872 622{
f1f41a6c 623 return v ? v->is_empty () : true;
de2b4872 624}
190183c5 625
930bdacf 626
f1f41a6c 627/* If V does not have space for NELEMS elements, call
628 V->reserve(NELEMS, EXACT). */
629template<typename T, typename A>
630inline bool
631vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false
632 MEM_STAT_DECL)
633{
634 bool extend = nelems ? !vec_safe_space (v, nelems) : false;
635 if (extend)
636 A::reserve (v, nelems, exact PASS_MEM_STAT);
637 return extend;
638}
2b15d2ba 639
f1f41a6c 640template<typename T, typename A>
641inline bool
642vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems MEM_STAT_DECL)
2b15d2ba 643{
f1f41a6c 644 return vec_safe_reserve (v, nelems, true PASS_MEM_STAT);
2b15d2ba 645}
646
190183c5 647
f1f41a6c 648/* Allocate GC memory for V with space for NELEMS slots. If NELEMS
649 is 0, V is initialized to NULL. */
de2b4872 650
f1f41a6c 651template<typename T, typename A>
652inline void
653vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems MEM_STAT_DECL)
de2b4872 654{
f1f41a6c 655 v = NULL;
656 vec_safe_reserve (v, nelems);
de2b4872 657}
190183c5 658
2b15d2ba 659
f1f41a6c 660/* Free the GC memory allocated by vector V and set it to NULL. */
2b15d2ba 661
f1f41a6c 662template<typename T, typename A>
663inline void
664vec_free (vec<T, A, vl_embed> *&v)
2b15d2ba 665{
f1f41a6c 666 A::release (v);
2b15d2ba 667}
668
f1f41a6c 669
670/* Grow V to length LEN. Allocate it, if necessary. */
671template<typename T, typename A>
672inline void
673vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len MEM_STAT_DECL)
2b15d2ba 674{
f1f41a6c 675 unsigned oldlen = vec_safe_length (v);
676 gcc_checking_assert (len >= oldlen);
677 vec_safe_reserve_exact (v, len - oldlen PASS_MEM_STAT);
678 v->quick_grow (len PASS_MEM_STAT);
2b15d2ba 679}
930bdacf 680
190183c5 681
f1f41a6c 682/* If V is NULL, allocate it. Call V->safe_grow_cleared(LEN). */
683template<typename T, typename A>
684inline void
685vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len MEM_STAT_DECL)
686{
687 unsigned oldlen = vec_safe_length (v);
688 vec_safe_grow (v, len PASS_MEM_STAT);
689 memset (&(v->address()[oldlen]), 0, sizeof (T) * (len - oldlen));
690}
190183c5 691
2b15d2ba 692
f1f41a6c 693/* If V is NULL return false, otherwise return V->iterate(IX, PTR). */
694template<typename T, typename A>
695inline bool
696vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr)
2b15d2ba 697{
f1f41a6c 698 if (v)
699 return v->iterate (ix, ptr);
2b15d2ba 700 else
701 {
702 *ptr = 0;
703 return false;
704 }
705}
706
f1f41a6c 707template<typename T, typename A>
708inline bool
709vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr)
2b15d2ba 710{
f1f41a6c 711 if (v)
712 return v->iterate (ix, ptr);
2b15d2ba 713 else
714 {
715 *ptr = 0;
716 return false;
717 }
718}
190183c5 719
de2b4872 720
f1f41a6c 721/* If V has no room for one more element, reallocate it. Then call
722 V->quick_push(OBJ). */
723template<typename T, typename A>
724inline T *
725vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj MEM_STAT_DECL)
726{
727 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
728 return v->quick_push (obj PASS_MEM_STAT);
729}
48148244 730
48148244 731
f1f41a6c 732/* if V has no room for one more element, reallocate it. Then call
733 V->quick_insert(IX, OBJ). */
734template<typename T, typename A>
735inline void
736vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
737 MEM_STAT_DECL)
738{
739 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
740 v->quick_insert (ix, obj);
741}
31adcf56 742
31adcf56 743
f1f41a6c 744/* If V is NULL, do nothing. Otherwise, call V->truncate(SIZE). */
745template<typename T, typename A>
746inline void
747vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size)
748{
749 if (v)
750 v->truncate (size);
751}
2ab2ce89 752
2ab2ce89 753
f1f41a6c 754/* If SRC is not NULL, return a pointer to a copy of it. */
755template<typename T, typename A>
756inline vec<T, A, vl_embed> *
757vec_safe_copy (vec<T, A, vl_embed> *src)
758{
759 return src ? src->copy () : NULL;
760}
2b15d2ba 761
f1f41a6c 762/* Copy the elements from SRC to the end of DST as if by memcpy.
763 Reallocate DST, if necessary. */
764template<typename T, typename A>
765inline void
766vec_safe_splice (vec<T, A, vl_embed> *&dst, vec<T, A, vl_embed> *src
767 MEM_STAT_DECL)
768{
769 unsigned src_len = vec_safe_length (src);
770 if (src_len)
771 {
772 vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len);
773 dst->splice (*src);
774 }
775}
2b15d2ba 776
2b15d2ba 777
f1f41a6c 778/* Index into vector. Return the IX'th element. IX must be in the
779 domain of the vector. */
2b15d2ba 780
f1f41a6c 781template<typename T, typename A>
782inline const T &
783vec<T, A, vl_embed>::operator[] (unsigned ix) const
784{
785 gcc_checking_assert (ix < pfx_.num_);
786 return data_[ix];
787}
2b15d2ba 788
f1f41a6c 789template<typename T, typename A>
790inline T &
791vec<T, A, vl_embed>::operator[] (unsigned ix)
2b15d2ba 792{
f1f41a6c 793 gcc_checking_assert (ix < pfx_.num_);
794 return data_[ix];
2b15d2ba 795}
796
de2b4872 797
f1f41a6c 798/* Get the final element of the vector, which must not be empty. */
2b15d2ba 799
f1f41a6c 800template<typename T, typename A>
801inline T &
802vec<T, A, vl_embed>::last (void)
2b15d2ba 803{
f1f41a6c 804 gcc_checking_assert (pfx_.num_ > 0);
805 return (*this)[pfx_.num_ - 1];
2b15d2ba 806}
807
808
f1f41a6c 809/* If this vector has space for NELEMS additional entries, return
810 true. You usually only need to use this if you are doing your
811 own vector reallocation, for instance on an embedded vector. This
812 returns true in exactly the same circumstances that vec::reserve
813 will. */
de2b4872 814
f1f41a6c 815template<typename T, typename A>
816inline bool
817vec<T, A, vl_embed>::space (unsigned nelems) const
818{
819 return pfx_.alloc_ - pfx_.num_ >= nelems;
820}
de2b4872 821
de2b4872 822
f1f41a6c 823/* Return iteration condition and update PTR to point to the IX'th
824 element of this vector. Use this to iterate over the elements of a
825 vector as follows,
de2b4872 826
f1f41a6c 827 for (ix = 0; vec<T, A>::iterate(v, ix, &ptr); ix++)
828 continue; */
de2b4872 829
f1f41a6c 830template<typename T, typename A>
831inline bool
832vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const
2b15d2ba 833{
f1f41a6c 834 if (ix < pfx_.num_)
835 {
836 *ptr = data_[ix];
837 return true;
838 }
839 else
840 {
841 *ptr = 0;
842 return false;
843 }
2b15d2ba 844}
845
930bdacf 846
f1f41a6c 847/* Return iteration condition and update *PTR to point to the
848 IX'th element of this vector. Use this to iterate over the
849 elements of a vector as follows,
190183c5 850
f1f41a6c 851 for (ix = 0; v->iterate(ix, &ptr); ix++)
852 continue;
07e8c04c 853
f1f41a6c 854 This variant is for vectors of objects. */
855
856template<typename T, typename A>
857inline bool
858vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const
2b15d2ba 859{
f1f41a6c 860 if (ix < pfx_.num_)
861 {
862 *ptr = CONST_CAST (T *, &data_[ix]);
863 return true;
864 }
865 else
2b15d2ba 866 {
f1f41a6c 867 *ptr = 0;
868 return false;
2b15d2ba 869 }
2b15d2ba 870}
930bdacf 871
930bdacf 872
f1f41a6c 873/* Return a pointer to a copy of this vector. */
c75b4594 874
f1f41a6c 875template<typename T, typename A>
876inline vec<T, A, vl_embed> *
877vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECL) const
2b15d2ba 878{
f1f41a6c 879 vec<T, A, vl_embed> *new_vec = NULL;
880 unsigned len = length ();
de2b4872 881 if (len)
2b15d2ba 882 {
f1f41a6c 883 vec_alloc (new_vec, len PASS_MEM_STAT);
de2b4872 884 new_vec->embedded_init (len, len);
f1f41a6c 885 memcpy (new_vec->address(), data_, sizeof (T) * len);
2b15d2ba 886 }
de2b4872 887 return new_vec;
888}
48e1416a 889
930bdacf 890
f1f41a6c 891/* Copy the elements from SRC to the end of this vector as if by memcpy.
892 The vector must have sufficient headroom available. */
930bdacf 893
f1f41a6c 894template<typename T, typename A>
895inline void
896vec<T, A, vl_embed>::splice (vec<T, A, vl_embed> &src)
897{
898 unsigned len = src.length();
899 if (len)
900 {
901 gcc_checking_assert (space (len));
902 memcpy (address() + length(), src.address(), len * sizeof (T));
903 pfx_.num_ += len;
904 }
905}
906
907template<typename T, typename A>
908inline void
909vec<T, A, vl_embed>::splice (vec<T, A, vl_embed> *src)
2b15d2ba 910{
f1f41a6c 911 if (src)
912 splice (*src);
2b15d2ba 913}
914
190183c5 915
f1f41a6c 916/* Push OBJ (a new element) onto the end of the vector. There must be
917 sufficient space in the vector. Return a pointer to the slot
918 where OBJ was inserted. */
930bdacf 919
f1f41a6c 920template<typename T, typename A>
921inline T *
922vec<T, A, vl_embed>::quick_push (const T &obj)
2b15d2ba 923{
f1f41a6c 924 gcc_checking_assert (space (1));
925 T *slot = &data_[pfx_.num_++];
926 *slot = obj;
927 return slot;
2b15d2ba 928}
929
190183c5 930
f1f41a6c 931/* Pop and return the last element off the end of the vector. */
24ffec38 932
f1f41a6c 933template<typename T, typename A>
934inline T &
935vec<T, A, vl_embed>::pop (void)
2b15d2ba 936{
f1f41a6c 937 gcc_checking_assert (length () > 0);
938 return data_[--pfx_.num_];
939}
2b15d2ba 940
2b15d2ba 941
f1f41a6c 942/* Set the length of the vector to SIZE. The new length must be less
943 than or equal to the current length. This is an O(1) operation. */
944
945template<typename T, typename A>
946inline void
947vec<T, A, vl_embed>::truncate (unsigned size)
948{
949 gcc_checking_assert (length () >= size);
950 pfx_.num_ = size;
2b15d2ba 951}
952
24ffec38 953
f1f41a6c 954/* Insert an element, OBJ, at the IXth position of this vector. There
955 must be sufficient space. */
2b15d2ba 956
f1f41a6c 957template<typename T, typename A>
958inline void
959vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj)
2b15d2ba 960{
f1f41a6c 961 gcc_checking_assert (length () < allocated ());
962 gcc_checking_assert (ix <= length ());
963 T *slot = &data_[ix];
964 memmove (slot + 1, slot, (pfx_.num_++ - ix) * sizeof (T));
965 *slot = obj;
2b15d2ba 966}
967
008f96d8 968
f1f41a6c 969/* Remove an element from the IXth position of this vector. Ordering of
970 remaining elements is preserved. This is an O(N) operation due to
971 memmove. */
008f96d8 972
f1f41a6c 973template<typename T, typename A>
974inline void
975vec<T, A, vl_embed>::ordered_remove (unsigned ix)
2b15d2ba 976{
f1f41a6c 977 gcc_checking_assert (ix < length());
978 T *slot = &data_[ix];
979 memmove (slot, slot + 1, (--pfx_.num_ - ix) * sizeof (T));
980}
981
982
983/* Remove an element from the IXth position of this vector. Ordering of
984 remaining elements is destroyed. This is an O(1) operation. */
985
986template<typename T, typename A>
987inline void
988vec<T, A, vl_embed>::unordered_remove (unsigned ix)
989{
990 gcc_checking_assert (ix < length());
991 data_[ix] = data_[--pfx_.num_];
992}
993
994
995/* Remove LEN elements starting at the IXth. Ordering is retained.
996 This is an O(N) operation due to memmove. */
997
998template<typename T, typename A>
999inline void
1000vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len)
1001{
1002 gcc_checking_assert (ix + len <= length());
1003 T *slot = &data_[ix];
1004 pfx_.num_ -= len;
1005 memmove (slot, slot + len, (pfx_.num_ - ix) * sizeof (T));
1006}
1007
1008
1009/* Sort the contents of this vector with qsort. CMP is the comparison
1010 function to pass to qsort. */
1011
1012template<typename T, typename A>
1013inline void
1014vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))
1015{
1016 ::qsort (address(), length(), sizeof (T), cmp);
1017}
1018
1019
1020/* Find and return the first position in which OBJ could be inserted
1021 without changing the ordering of this vector. LESSTHAN is a
1022 function that returns true if the first argument is strictly less
1023 than the second. */
1024
1025template<typename T, typename A>
1026unsigned
1027vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1028 const
1029{
1030 unsigned int len = length ();
1031 unsigned int half, middle;
1032 unsigned int first = 0;
1033 while (len > 0)
2b15d2ba 1034 {
f1f41a6c 1035 half = len / 2;
1036 middle = first;
1037 middle += half;
1038 T middle_elem = (*this)[middle];
1039 if (lessthan (middle_elem, obj))
1040 {
1041 first = middle;
1042 ++first;
1043 len = len - half - 1;
1044 }
1045 else
1046 len = half;
2b15d2ba 1047 }
f1f41a6c 1048 return first;
2b15d2ba 1049}
1050
2b15d2ba 1051
f1f41a6c 1052/* Return the number of bytes needed to embed an instance of an
1053 embeddable vec inside another data structure.
de2b4872 1054
f1f41a6c 1055 Use these methods to determine the required size and initialization
1056 of a vector V of type T embedded within another structure (as the
1057 final member):
1058
1059 size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc);
1060 void v->embedded_init(unsigned alloc, unsigned num);
1061
1062 These allow the caller to perform the memory allocation. */
1063
1064template<typename T, typename A>
1065inline size_t
1066vec<T, A, vl_embed>::embedded_size (unsigned alloc)
2b15d2ba 1067{
f1f41a6c 1068 typedef vec<T, A, vl_embed> vec_embedded;
1069 return offsetof (vec_embedded, data_) + alloc * sizeof (T);
2b15d2ba 1070}
1071
190183c5 1072
f1f41a6c 1073/* Initialize the vector to contain room for ALLOC elements and
1074 NUM active elements. */
de2b4872 1075
f1f41a6c 1076template<typename T, typename A>
1077inline void
1078vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num)
2b15d2ba 1079{
f1f41a6c 1080 pfx_.alloc_ = alloc;
1081 pfx_.num_ = num;
2b15d2ba 1082}
1083
190183c5 1084
f1f41a6c 1085/* Grow the vector to a specific length. LEN must be as long or longer than
1086 the current length. The new elements are uninitialized. */
2b15d2ba 1087
f1f41a6c 1088template<typename T, typename A>
1089inline void
1090vec<T, A, vl_embed>::quick_grow (unsigned len)
2b15d2ba 1091{
f1f41a6c 1092 gcc_checking_assert (length () <= len && len <= pfx_.alloc_);
1093 pfx_.num_ = len;
2b15d2ba 1094}
1095
190183c5 1096
f1f41a6c 1097/* Grow the vector to a specific length. LEN must be as long or longer than
1098 the current length. The new elements are initialized to zero. */
2b15d2ba 1099
f1f41a6c 1100template<typename T, typename A>
1101inline void
1102vec<T, A, vl_embed>::quick_grow_cleared (unsigned len)
2b15d2ba 1103{
f1f41a6c 1104 unsigned oldlen = length ();
1105 quick_grow (len);
1106 memset (&(address()[oldlen]), 0, sizeof (T) * (len - oldlen));
2b15d2ba 1107}
1108
046bfc77 1109
f1f41a6c 1110/* Garbage collection support for vec<T, A, vl_embed>. */
046bfc77 1111
de2b4872 1112template<typename T>
de2b4872 1113void
f1f41a6c 1114gt_ggc_mx (vec<T, va_gc> *v)
2b15d2ba 1115{
f1f41a6c 1116 extern void gt_ggc_mx (T &);
1117 for (unsigned i = 0; i < v->length (); i++)
1118 gt_ggc_mx ((*v)[i]);
2b15d2ba 1119}
1120
de2b4872 1121template<typename T>
de2b4872 1122void
f1f41a6c 1123gt_ggc_mx (vec<T, va_gc_atomic, vl_embed> *v ATTRIBUTE_UNUSED)
2b15d2ba 1124{
f1f41a6c 1125 /* Nothing to do. Vectors of atomic types wrt GC do not need to
1126 be traversed. */
2b15d2ba 1127}
1128
e85c2c2d 1129
f1f41a6c 1130/* PCH support for vec<T, A, vl_embed>. */
2b15d2ba 1131
f1f41a6c 1132template<typename T, typename A>
de2b4872 1133void
f1f41a6c 1134gt_pch_nx (vec<T, A, vl_embed> *v)
2b15d2ba 1135{
f1f41a6c 1136 extern void gt_pch_nx (T &);
1137 for (unsigned i = 0; i < v->length (); i++)
1138 gt_pch_nx ((*v)[i]);
2b15d2ba 1139}
1140
f1f41a6c 1141template<typename T, typename A>
1142void
1143gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1144{
1145 for (unsigned i = 0; i < v->length (); i++)
1146 op (&((*v)[i]), cookie);
1147}
190183c5 1148
f1f41a6c 1149template<typename T, typename A>
de2b4872 1150void
f1f41a6c 1151gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
de2b4872 1152{
f1f41a6c 1153 extern void gt_pch_nx (T *, gt_pointer_operator, void *);
1154 for (unsigned i = 0; i < v->length (); i++)
1155 gt_pch_nx (&((*v)[i]), op, cookie);
de2b4872 1156}
930bdacf 1157
de2b4872 1158
f1f41a6c 1159/* Space efficient vector. These vectors can grow dynamically and are
1160 allocated together with their control data. They are suited to be
1161 included in data structures. Prior to initial allocation, they
1162 only take a single word of storage.
1163
1164 These vectors are implemented as a pointer to an embeddable vector.
1165 The semantics allow for this pointer to be NULL to represent empty
1166 vectors. This way, empty vectors occupy minimal space in the
1167 structure containing them.
1168
1169 Properties:
1170
1171 - The whole vector and control data are allocated in a single
1172 contiguous block.
1173 - The whole vector may be re-allocated.
1174 - Vector data may grow and shrink.
1175 - Access and manipulation requires a pointer test and
1176 indirection.
1177 - It requires 1 word of storage (prior to vector allocation).
1178
1179
1180 Limitations:
1181
1182 These vectors must be PODs because they are stored in unions.
1183 (http://en.wikipedia.org/wiki/Plain_old_data_structures).
1184 As long as we use C++03, we cannot have constructors nor
1185 destructors in classes that are stored in unions. */
1186
1187template<typename T, typename A>
1188class vec<T, A, vl_ptr>
1189{
1190public:
1191 /* Memory allocation and deallocation for the embedded vector.
1192 Needed because we cannot have proper ctors/dtors defined. */
1193 void create (unsigned nelems CXX_MEM_STAT_INFO);
1194 void release (void);
1195
1196 /* Vector operations. */
1197 bool exists (void) const
1198 { return vec_ != NULL; }
1199
1200 bool is_empty (void) const
1201 { return vec_ ? vec_->is_empty() : true; }
1202
1203 unsigned length (void) const
1204 { return vec_ ? vec_->length() : 0; }
1205
1206 T *address (void)
1207 { return vec_ ? vec_->data_ : NULL; }
1208
1209 const T *address (void) const
1210 { return vec_ ? vec_->data_ : NULL; }
1211
1212 const T &operator[] (unsigned ix) const
1213 { return (*vec_)[ix]; }
1214
1215 bool operator!=(const vec &other) const
1216 { return !(*this == other); }
1217
1218 bool operator==(const vec &other) const
1219 { return address() == other.address(); }
1220
1221 T &operator[] (unsigned ix)
1222 { return (*vec_)[ix]; }
1223
1224 T &last (void)
1225 { return vec_->last(); }
1226
1227 bool space (int nelems) const
1228 { return vec_ ? vec_->space (nelems) : nelems == 0; }
1229
1230 bool iterate (unsigned ix, T *p) const;
1231 bool iterate (unsigned ix, T **p) const;
1232 vec copy (ALONE_CXX_MEM_STAT_INFO) const;
1233 bool reserve (unsigned, bool = false CXX_MEM_STAT_INFO);
1234 bool reserve_exact (unsigned CXX_MEM_STAT_INFO);
1235 void splice (vec &);
1236 void safe_splice (vec & CXX_MEM_STAT_INFO);
1237 T *quick_push (const T &);
1238 T *safe_push (const T &CXX_MEM_STAT_INFO);
1239 T &pop (void);
1240 void truncate (unsigned);
1241 void safe_grow (unsigned CXX_MEM_STAT_INFO);
1242 void safe_grow_cleared (unsigned CXX_MEM_STAT_INFO);
1243 void quick_grow (unsigned);
1244 void quick_grow_cleared (unsigned);
1245 void quick_insert (unsigned, const T &);
1246 void safe_insert (unsigned, const T & CXX_MEM_STAT_INFO);
1247 void ordered_remove (unsigned);
1248 void unordered_remove (unsigned);
1249 void block_remove (unsigned, unsigned);
1250 void qsort (int (*) (const void *, const void *));
1251 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
1252
1253 template<typename T1>
1254 friend void va_stack::alloc(vec<T1, va_stack, vl_ptr>&, unsigned,
1255 vec<T1, va_stack, vl_embed> *);
1256
1257private:
1258 vec<T, A, vl_embed> *vec_;
1259};
1260
1261
1262/* Empty specialization for GC allocation. This will prevent GC
1263 vectors from using the vl_ptr layout. FIXME: This is needed to
1264 circumvent limitations in the GTY machinery. */
de2b4872 1265
2b15d2ba 1266template<typename T>
f1f41a6c 1267class vec<T, va_gc, vl_ptr>
2b15d2ba 1268{
f1f41a6c 1269};
2b15d2ba 1270
190183c5 1271
f1f41a6c 1272/* Allocate heap memory for pointer V and create the internal vector
1273 with space for NELEMS elements. If NELEMS is 0, the internal
1274 vector is initialized to empty. */
930bdacf 1275
2b15d2ba 1276template<typename T>
f1f41a6c 1277inline void
1278vec_alloc (vec<T> *&v, unsigned nelems MEM_STAT_DECL)
2b15d2ba 1279{
f1f41a6c 1280 v = new vec<T>;
1281 v->create (nelems PASS_MEM_STAT);
2b15d2ba 1282}
1283
190183c5 1284
f1f41a6c 1285/* Conditionally allocate heap memory for VEC and its internal vector. */
930bdacf 1286
2b15d2ba 1287template<typename T>
f1f41a6c 1288inline void
1289vec_check_alloc (vec<T, va_heap> *&vec, unsigned nelems MEM_STAT_DECL)
2b15d2ba 1290{
f1f41a6c 1291 if (!vec)
1292 vec_alloc (vec, nelems PASS_MEM_STAT);
2b15d2ba 1293}
1294
190183c5 1295
f1f41a6c 1296/* Free the heap memory allocated by vector V and set it to NULL. */
dbd44b25 1297
2b15d2ba 1298template<typename T>
f1f41a6c 1299inline void
1300vec_free (vec<T> *&v)
2b15d2ba 1301{
f1f41a6c 1302 if (v == NULL)
1303 return;
1304
1305 v->release ();
1306 delete v;
1307 v = NULL;
2b15d2ba 1308}
930bdacf 1309
de5ab3f1 1310
f1f41a6c 1311/* Allocate a new stack vector with space for exactly NELEMS objects.
1312 If NELEMS is zero, NO vector is created.
48e1416a 1313
f1f41a6c 1314 For the stack allocator, no memory is really allocated. The vector
1315 is initialized to be at address SPACE and contain NELEMS slots.
1316 Memory allocation actually occurs in the expansion of VEC_alloc.
145fce5e 1317
f1f41a6c 1318 Usage notes:
1319
1320 * This does not allocate an instance of vec<T, A>. It allocates the
1321 actual vector of elements (i.e., vec<T, A, vl_embed>) inside a
1322 vec<T, A> instance.
1323
1324 * This allocator must always be a macro:
1325
1326 We support a vector which starts out with space on the stack and
1327 switches to heap space when forced to reallocate. This works a
1328 little differently. In the case of stack vectors, vec_alloc will
1329 expand to a call to vec_alloc_1 that calls XALLOCAVAR to request
1330 the initial allocation. This uses alloca to get the initial
1331 space. Since alloca can not be usefully called in an inline
1332 function, vec_alloc must always be a macro.
1333
1334 Important limitations of stack vectors:
1335
1336 - Only the initial allocation will be made using alloca, so pass
1337 a reasonable estimate that doesn't use too much stack space;
1338 don't pass zero.
1339
1340 - Don't return a stack-allocated vector from the function which
1341 allocated it. */
1342
1343#define vec_stack_alloc(T,V,N) \
1344 do { \
1345 typedef vec<T, va_stack, vl_embed> stackv; \
1346 va_stack::alloc (V, N, XALLOCAVAR (stackv, stackv::embedded_size (N)));\
1347 } while (0)
1348
1349
1350/* Return iteration condition and update PTR to point to the IX'th
1351 element of this vector. Use this to iterate over the elements of a
1352 vector as follows,
1353
1354 for (ix = 0; v.iterate(ix, &ptr); ix++)
1355 continue; */
1356
1357template<typename T, typename A>
1358inline bool
1359vec<T, A, vl_ptr>::iterate (unsigned ix, T *ptr) const
72e5da43 1360{
f1f41a6c 1361 if (vec_)
1362 return vec_->iterate (ix, ptr);
1363 else
2b15d2ba 1364 {
f1f41a6c 1365 *ptr = 0;
1366 return false;
2b15d2ba 1367 }
4cf7067a 1368}
1369
de2b4872 1370
f1f41a6c 1371/* Return iteration condition and update *PTR to point to the
1372 IX'th element of this vector. Use this to iterate over the
1373 elements of a vector as follows,
1374
1375 for (ix = 0; v->iterate(ix, &ptr); ix++)
1376 continue;
f7f05a07 1377
f1f41a6c 1378 This variant is for vectors of objects. */
f7f05a07 1379
f1f41a6c 1380template<typename T, typename A>
1381inline bool
1382vec<T, A, vl_ptr>::iterate (unsigned ix, T **ptr) const
2b15d2ba 1383{
f1f41a6c 1384 if (vec_)
1385 return vec_->iterate (ix, ptr);
1386 else
de2b4872 1387 {
f1f41a6c 1388 *ptr = 0;
1389 return false;
de2b4872 1390 }
f1f41a6c 1391}
1392
1393
1394/* Convenience macro for forward iteration. */
1395#define FOR_EACH_VEC_ELT(V, I, P) \
1396 for (I = 0; (V).iterate ((I), &(P)); ++(I))
1397
1398#define FOR_EACH_VEC_SAFE_ELT(V, I, P) \
1399 for (I = 0; vec_safe_iterate ((V), (I), &(P)); ++(I))
1400
1401/* Likewise, but start from FROM rather than 0. */
1402#define FOR_EACH_VEC_ELT_FROM(V, I, P, FROM) \
1403 for (I = (FROM); (V).iterate ((I), &(P)); ++(I))
de2b4872 1404
f1f41a6c 1405/* Convenience macro for reverse iteration. */
1406#define FOR_EACH_VEC_ELT_REVERSE(V, I, P) \
1407 for (I = (V).length () - 1; \
1408 (V).iterate ((I), &(P)); \
1409 (I)--)
1410
1411#define FOR_EACH_VEC_SAFE_ELT_REVERSE(V, I, P) \
1412 for (I = vec_safe_length (V) - 1; \
1413 vec_safe_iterate ((V), (I), &(P)); \
1414 (I)--)
1415
1416
1417/* Return a copy of this vector. */
1418
1419template<typename T, typename A>
1420inline vec<T, A, vl_ptr>
1421vec<T, A, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
1422{
1423 vec<T, A, vl_ptr> new_vec = vec<T, A, vl_ptr>();
1424 if (length ())
1425 new_vec.vec_ = vec_->copy ();
1426 return new_vec;
f7f05a07 1427}
1428
f7f05a07 1429
f1f41a6c 1430/* Ensure that the vector has at least RESERVE slots available (if
1431 EXACT is false), or exactly RESERVE slots available (if EXACT is
1432 true).
f7f05a07 1433
f1f41a6c 1434 This may create additional headroom if EXACT is false.
1435
1436 Note that this can cause the embedded vector to be reallocated.
1437 Returns true iff reallocation actually occurred. */
1438
1439template<typename T, typename A>
1440inline bool
1441vec<T, A, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
2b15d2ba 1442{
f1f41a6c 1443 bool extend = nelems ? !space (nelems) : false;
1444 if (extend)
1445 A::reserve (vec_, nelems, exact PASS_MEM_STAT);
1446 return extend;
1447}
1448
de2b4872 1449
f1f41a6c 1450/* Ensure that this vector has exactly NELEMS slots available. This
1451 will not create additional headroom. Note this can cause the
1452 embedded vector to be reallocated. Returns true iff reallocation
1453 actually occurred. */
de2b4872 1454
f1f41a6c 1455template<typename T, typename A>
1456inline bool
1457vec<T, A, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
1458{
1459 return reserve (nelems, true PASS_MEM_STAT);
1460}
1461
1462
1463/* Create the internal vector and reserve NELEMS for it. This is
1464 exactly like vec::reserve, but the internal vector is
1465 unconditionally allocated from scratch. The old one, if it
1466 existed, is lost. */
1467
1468template<typename T, typename A>
1469inline void
1470vec<T, A, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
1471{
1472 vec_ = NULL;
1473 if (nelems > 0)
1474 reserve_exact (nelems PASS_MEM_STAT);
1475}
1476
1477
1478/* Free the memory occupied by the embedded vector. */
1479
1480template<typename T, typename A>
1481inline void
1482vec<T, A, vl_ptr>::release (void)
1483{
1484 if (vec_)
1485 A::release (vec_);
1486}
1487
1488
1489/* Copy the elements from SRC to the end of this vector as if by memcpy.
1490 SRC and this vector must be allocated with the same memory
1491 allocation mechanism. This vector is assumed to have sufficient
1492 headroom available. */
1493
1494template<typename T, typename A>
1495inline void
1496vec<T, A, vl_ptr>::splice (vec<T, A, vl_ptr> &src)
1497{
1498 if (src.vec_)
1499 vec_->splice (*(src.vec_));
1500}
1501
1502
1503/* Copy the elements in SRC to the end of this vector as if by memcpy.
1504 SRC and this vector must be allocated with the same mechanism.
1505 If there is not enough headroom in this vector, it will be reallocated
1506 as needed. */
1507
1508template<typename T, typename A>
1509inline void
1510vec<T, A, vl_ptr>::safe_splice (vec<T, A, vl_ptr> &src MEM_STAT_DECL)
1511{
1512 if (src.length())
2b15d2ba 1513 {
f1f41a6c 1514 reserve_exact (src.length());
1515 splice (src);
2b15d2ba 1516 }
f1f41a6c 1517}
1518
1519
1520/* Push OBJ (a new element) onto the end of the vector. There must be
1521 sufficient space in the vector. Return a pointer to the slot
1522 where OBJ was inserted. */
1523
1524template<typename T, typename A>
1525inline T *
1526vec<T, A, vl_ptr>::quick_push (const T &obj)
1527{
1528 return vec_->quick_push (obj);
1529}
1530
1531
1532/* Push a new element OBJ onto the end of this vector. Reallocates
1533 the embedded vector, if needed. Return a pointer to the slot where
1534 OBJ was inserted. */
1535
1536template<typename T, typename A>
1537inline T *
1538vec<T, A, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
1539{
1540 reserve (1, false PASS_MEM_STAT);
1541 return quick_push (obj);
1542}
1543
de2b4872 1544
f1f41a6c 1545/* Pop and return the last element off the end of the vector. */
1546
1547template<typename T, typename A>
1548inline T &
1549vec<T, A, vl_ptr>::pop (void)
1550{
1551 return vec_->pop ();
1552}
1553
1554
1555/* Set the length of the vector to LEN. The new length must be less
1556 than or equal to the current length. This is an O(1) operation. */
1557
1558template<typename T, typename A>
1559inline void
1560vec<T, A, vl_ptr>::truncate (unsigned size)
1561{
1562 if (vec_)
1563 vec_->truncate (size);
1564 else
1565 gcc_checking_assert (size == 0);
1566}
1567
1568
1569/* Grow the vector to a specific length. LEN must be as long or
1570 longer than the current length. The new elements are
1571 uninitialized. Reallocate the internal vector, if needed. */
1572
1573template<typename T, typename A>
1574inline void
1575vec<T, A, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
1576{
1577 unsigned oldlen = length ();
1578 gcc_checking_assert (oldlen <= len);
1579 reserve_exact (len - oldlen PASS_MEM_STAT);
1580 vec_->quick_grow (len);
1581}
1582
1583
1584/* Grow the embedded vector to a specific length. LEN must be as
1585 long or longer than the current length. The new elements are
1586 initialized to zero. Reallocate the internal vector, if needed. */
1587
1588template<typename T, typename A>
1589inline void
1590vec<T, A, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
1591{
1592 unsigned oldlen = length ();
1593 safe_grow (len PASS_MEM_STAT);
1594 memset (&(address()[oldlen]), 0, sizeof (T) * (len - oldlen));
1595}
1596
1597
1598/* Same as vec::safe_grow but without reallocation of the internal vector.
1599 If the vector cannot be extended, a runtime assertion will be triggered. */
1600
1601template<typename T, typename A>
1602inline void
1603vec<T, A, vl_ptr>::quick_grow (unsigned len)
1604{
1605 gcc_checking_assert (vec_);
1606 vec_->quick_grow (len);
1607}
1608
1609
1610/* Same as vec::quick_grow_cleared but without reallocation of the
1611 internal vector. If the vector cannot be extended, a runtime
1612 assertion will be triggered. */
1613
1614template<typename T, typename A>
1615inline void
1616vec<T, A, vl_ptr>::quick_grow_cleared (unsigned len)
1617{
1618 gcc_checking_assert (vec_);
1619 vec_->quick_grow_cleared (len);
1620}
1621
1622
1623/* Insert an element, OBJ, at the IXth position of this vector. There
1624 must be sufficient space. */
1625
1626template<typename T, typename A>
1627inline void
1628vec<T, A, vl_ptr>::quick_insert (unsigned ix, const T &obj)
1629{
1630 vec_->quick_insert (ix, obj);
1631}
1632
1633
1634/* Insert an element, OBJ, at the IXth position of the vector.
1635 Reallocate the embedded vector, if necessary. */
1636
1637template<typename T, typename A>
1638inline void
1639vec<T, A, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
1640{
1641 reserve (1, false PASS_MEM_STAT);
1642 quick_insert (ix, obj);
1643}
1644
1645
1646/* Remove an element from the IXth position of this vector. Ordering of
1647 remaining elements is preserved. This is an O(N) operation due to
1648 a memmove. */
1649
1650template<typename T, typename A>
1651inline void
1652vec<T, A, vl_ptr>::ordered_remove (unsigned ix)
1653{
1654 vec_->ordered_remove (ix);
1655}
1656
1657
1658/* Remove an element from the IXth position of this vector. Ordering
1659 of remaining elements is destroyed. This is an O(1) operation. */
1660
1661template<typename T, typename A>
1662inline void
1663vec<T, A, vl_ptr>::unordered_remove (unsigned ix)
1664{
1665 vec_->unordered_remove (ix);
1666}
1667
1668
1669/* Remove LEN elements starting at the IXth. Ordering is retained.
1670 This is an O(N) operation due to memmove. */
1671
1672template<typename T, typename A>
1673inline void
1674vec<T, A, vl_ptr>::block_remove (unsigned ix, unsigned len)
1675{
1676 vec_->block_remove (ix, len);
1677}
1678
1679
1680/* Sort the contents of this vector with qsort. CMP is the comparison
1681 function to pass to qsort. */
1682
1683template<typename T, typename A>
1684inline void
1685vec<T, A, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
1686{
1687 if (vec_)
1688 vec_->qsort (cmp);
1689}
1690
1691
1692/* Find and return the first position in which OBJ could be inserted
1693 without changing the ordering of this vector. LESSTHAN is a
1694 function that returns true if the first argument is strictly less
1695 than the second. */
1696
1697template<typename T, typename A>
1698inline unsigned
1699vec<T, A, vl_ptr>::lower_bound (T obj, bool (*lessthan)(const T &, const T &)) const
1700{
1701 return vec_ ? vec_->lower_bound (obj, lessthan) : 0;
f7f05a07 1702}
1703
f1f41a6c 1704#endif // GCC_VEC_H