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