OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [lib/] [gcc/] [or1knd-elf/] [4.8.0/] [plugin/] [include/] [vec.h] - Blame information for rev 35

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.