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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [vec.h] - Blame information for rev 823

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Vector API for GDB.
2
   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3
   Contributed by Nathan Sidwell <nathan@codesourcery.com>
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#if !defined (GDB_VEC_H)
21
#define GDB_VEC_H
22
 
23
#include <stddef.h>
24
#include "gdb_string.h"
25
#include "gdb_assert.h"
26
 
27
/* The macros here implement a set of templated vector types and
28
   associated interfaces.  These templates are implemented with
29
   macros, as we're not in C++ land.  The interface functions are
30
   typesafe and use static inline functions, sometimes backed by
31
   out-of-line generic functions.
32
 
33
   Because of the different behavior of structure objects, scalar
34
   objects and of pointers, there are three flavors, one for each of
35
   these variants.  Both the structure object and pointer variants
36
   pass pointers to objects around -- in the former case the pointers
37
   are stored into the vector and in the latter case the pointers are
38
   dereferenced and the objects copied into the vector.  The scalar
39
   object variant is suitable for int-like objects, and the vector
40
   elements are returned by value.
41
 
42
   There are both 'index' and 'iterate' accessors.  The iterator
43
   returns a boolean iteration condition and updates the iteration
44
   variable passed by reference.  Because the iterator will be
45
   inlined, the address-of can be optimized away.
46
 
47
   The vectors are implemented using the trailing array idiom, thus
48
   they are not resizeable without changing the address of the vector
49
   object itself.  This means you cannot have variables or fields of
50
   vector type -- always use a pointer to a vector.  The one exception
51
   is the final field of a structure, which could be a vector type.
52
   You will have to use the embedded_size & embedded_init calls to
53
   create such objects, and they will probably not be resizeable (so
54
   don't use the 'safe' allocation variants).  The trailing array
55
   idiom is used (rather than a pointer to an array of data), because,
56
   if we allow NULL to also represent an empty vector, empty vectors
57
   occupy minimal space in the structure containing them.
58
 
59
   Each operation that increases the number of active elements is
60
   available in 'quick' and 'safe' variants.  The former presumes that
61
   there is sufficient allocated space for the operation to succeed
62
   (it dies if there is not).  The latter will reallocate the
63
   vector, if needed.  Reallocation causes an exponential increase in
64
   vector size.  If you know you will be adding N elements, it would
65
   be more efficient to use the reserve operation before adding the
66
   elements with the 'quick' operation.  This will ensure there are at
67
   least as many elements as you ask for, it will exponentially
68
   increase if there are too few spare slots.  If you want reserve a
69
   specific number of slots, but do not want the exponential increase
70
   (for instance, you know this is the last allocation), use a
71
   negative number for reservation.  You can also create a vector of a
72
   specific size from the get go.
73
 
74
   You should prefer the push and pop operations, as they append and
75
   remove from the end of the vector. If you need to remove several
76
   items in one go, use the truncate operation.  The insert and remove
77
   operations allow you to change elements in the middle of the
78
   vector.  There are two remove operations, one which preserves the
79
   element ordering 'ordered_remove', and one which does not
80
   'unordered_remove'.  The latter function copies the end element
81
   into the removed slot, rather than invoke a memmove operation.  The
82
   'lower_bound' function will determine where to place an item in the
83
   array using insert that will maintain sorted order.
84
 
85
   If you need to directly manipulate a vector, then the 'address'
86
   accessor will return the address of the start of the vector.  Also
87
   the 'space' predicate will tell you whether there is spare capacity
88
   in the vector.  You will not normally need to use these two functions.
89
 
90
   Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro.
91
   Variables of vector type are declared using a VEC(TYPEDEF) macro.
92
   The characters O, P and I indicate whether TYPEDEF is a pointer
93
   (P), object (O) or integral (I) type.  Be careful to pick the
94
   correct one, as you'll get an awkward and inefficient API if you
95
   use the wrong one.  There is a check, which results in a
96
   compile-time warning, for the P and I versions, but there is no
97
   check for the O versions, as that is not possible in plain C.
98
 
99
   An example of their use would be,
100
 
101
   DEF_VEC_P(tree);   // non-managed tree vector.
102
 
103
   struct my_struct {
104
     VEC(tree) *v;      // A (pointer to) a vector of tree pointers.
105
   };
106
 
107
   struct my_struct *s;
108
 
109
   if (VEC_length(tree, s->v)) { we have some contents }
110
   VEC_safe_push(tree, s->v, decl); // append some decl onto the end
111
   for (ix = 0; VEC_iterate(tree, s->v, ix, elt); ix++)
112
     { do something with elt }
113
 
114
*/
115
 
116
/* Macros to invoke API calls.  A single macro works for both pointer
117
   and object vectors, but the argument and return types might well be
118
   different.  In each macro, T is the typedef of the vector elements.
119
   Some of these macros pass the vector, V, by reference (by taking
120
   its address), this is noted in the descriptions.  */
121
 
122
/* Length of vector
123
   unsigned VEC_T_length(const VEC(T) *v);
124
 
125
   Return the number of active elements in V.  V can be NULL, in which
126
   case zero is returned.  */
127
 
128
#define VEC_length(T,V) (VEC_OP(T,length)(V))
129
 
130
 
131
/* Check if vector is empty
132
   int VEC_T_empty(const VEC(T) *v);
133
 
134
   Return nonzero if V is an empty vector (or V is NULL), zero otherwise.  */
135
 
136
#define VEC_empty(T,V)  (VEC_length (T,V) == 0)
137
 
138
 
139
/* Get the final element of the vector.
140
   T VEC_T_last(VEC(T) *v); // Integer
141
   T VEC_T_last(VEC(T) *v); // Pointer
142
   T *VEC_T_last(VEC(T) *v); // Object
143
 
144
   Return the final element.  V must not be empty.  */
145
 
146
#define VEC_last(T,V)   (VEC_OP(T,last)(V VEC_ASSERT_INFO))
147
 
148
/* Index into vector
149
   T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
150
   T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
151
   T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
152
 
153
   Return the IX'th element.  If IX must be in the domain of V.  */
154
 
155
#define VEC_index(T,V,I) (VEC_OP(T,index)(V,I VEC_ASSERT_INFO))
156
 
157
/* Iterate over vector
158
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
159
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
160
   int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
161
 
162
   Return iteration condition and update PTR to point to the IX'th
163
   element.  At the end of iteration, sets PTR to NULL.  Use this to
164
   iterate over the elements of a vector as follows,
165
 
166
     for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
167
       continue;  */
168
 
169
#define VEC_iterate(T,V,I,P)    (VEC_OP(T,iterate)(V,I,&(P)))
170
 
171
/* Allocate new vector.
172
   VEC(T,A) *VEC_T_alloc(int reserve);
173
 
174
   Allocate a new vector with space for RESERVE objects.  If RESERVE
175
   is zero, NO vector is created.  */
176
 
177
#define VEC_alloc(T,N)  (VEC_OP(T,alloc)(N))
178
 
179
/* Free a vector.
180
   void VEC_T_free(VEC(T,A) *&);
181
 
182
   Free a vector and set it to NULL.  */
183
 
184
#define VEC_free(T,V)   (VEC_OP(T,free)(&V))
185
 
186
/* Use these to determine the required size and initialization of a
187
   vector embedded within another structure (as the final member).
188
 
189
   size_t VEC_T_embedded_size(int reserve);
190
   void VEC_T_embedded_init(VEC(T) *v, int reserve);
191
 
192
   These allow the caller to perform the memory allocation.  */
193
 
194
#define VEC_embedded_size(T,N)   (VEC_OP(T,embedded_size)(N))
195
#define VEC_embedded_init(T,O,N) (VEC_OP(T,embedded_init)(VEC_BASE(O),N))
196
 
197
/* Copy a vector.
198
   VEC(T,A) *VEC_T_copy(VEC(T) *);
199
 
200
   Copy the live elements of a vector into a new vector.  The new and
201
   old vectors need not be allocated by the same mechanism.  */
202
 
203
#define VEC_copy(T,V) (VEC_OP(T,copy)(V))
204
 
205
/* Determine if a vector has additional capacity.
206
 
207
   int VEC_T_space (VEC(T) *v,int reserve)
208
 
209
   If V has space for RESERVE additional entries, return nonzero.  You
210
   usually only need to use this if you are doing your own vector
211
   reallocation, for instance on an embedded vector.  This returns
212
   nonzero in exactly the same circumstances that VEC_T_reserve
213
   will.  */
214
 
215
#define VEC_space(T,V,R) (VEC_OP(T,space)(V,R VEC_ASSERT_INFO))
216
 
217
/* Reserve space.
218
   int VEC_T_reserve(VEC(T,A) *&v, int reserve);
219
 
220
   Ensure that V has at least abs(RESERVE) slots available.  The
221
   signedness of RESERVE determines the reallocation behavior.  A
222
   negative value will not create additional headroom beyond that
223
   requested.  A positive value will create additional headroom.  Note
224
   this can cause V to be reallocated.  Returns nonzero iff
225
   reallocation actually occurred.  */
226
 
227
#define VEC_reserve(T,V,R) (VEC_OP(T,reserve)(&(V),R VEC_ASSERT_INFO))
228
 
229
/* Push object with no reallocation
230
   T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
231
   T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
232
   T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
233
 
234
   Push a new element onto the end, returns a pointer to the slot
235
   filled in. For object vectors, the new value can be NULL, in which
236
   case NO initialization is performed.  There must
237
   be sufficient space in the vector.  */
238
 
239
#define VEC_quick_push(T,V,O) (VEC_OP(T,quick_push)(V,O VEC_ASSERT_INFO))
240
 
241
/* Push object with reallocation
242
   T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Integer
243
   T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Pointer
244
   T *VEC_T_safe_push (VEC(T,A) *&v, T *obj); // Object
245
 
246
   Push a new element onto the end, returns a pointer to the slot
247
   filled in. For object vectors, the new value can be NULL, in which
248
   case NO initialization is performed.  Reallocates V, if needed.  */
249
 
250
#define VEC_safe_push(T,V,O) (VEC_OP(T,safe_push)(&(V),O VEC_ASSERT_INFO))
251
 
252
/* Pop element off end
253
   T VEC_T_pop (VEC(T) *v);             // Integer
254
   T VEC_T_pop (VEC(T) *v);             // Pointer
255
   void VEC_T_pop (VEC(T) *v);          // Object
256
 
257
   Pop the last element off the end. Returns the element popped, for
258
   pointer vectors.  */
259
 
260
#define VEC_pop(T,V)    (VEC_OP(T,pop)(V VEC_ASSERT_INFO))
261
 
262
/* Truncate to specific length
263
   void VEC_T_truncate (VEC(T) *v, unsigned len);
264
 
265
   Set the length as specified.  The new length must be less than or
266
   equal to the current length.  This is an O(1) operation.  */
267
 
268
#define VEC_truncate(T,V,I)             \
269
        (VEC_OP(T,truncate)(V,I VEC_ASSERT_INFO))
270
 
271
/* Grow to a specific length.
272
   void VEC_T_safe_grow (VEC(T,A) *&v, int len);
273
 
274
   Grow the vector to a specific length.  The LEN must be as
275
   long or longer than the current length.  The new elements are
276
   uninitialized.  */
277
 
278
#define VEC_safe_grow(T,V,I)            \
279
        (VEC_OP(T,safe_grow)(&(V),I VEC_ASSERT_INFO))
280
 
281
/* Replace element
282
   T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
283
   T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
284
   T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val);  // Object
285
 
286
   Replace the IXth element of V with a new value, VAL.  For pointer
287
   vectors returns the original value. For object vectors returns a
288
   pointer to the new value.  For object vectors the new value can be
289
   NULL, in which case no overwriting of the slot is actually
290
   performed.  */
291
 
292
#define VEC_replace(T,V,I,O) (VEC_OP(T,replace)(V,I,O VEC_ASSERT_INFO))
293
 
294
/* Insert object with no reallocation
295
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
296
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
297
   T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
298
 
299
   Insert an element, VAL, at the IXth position of V. Return a pointer
300
   to the slot created.  For vectors of object, the new value can be
301
   NULL, in which case no initialization of the inserted slot takes
302
   place. There must be sufficient space.  */
303
 
304
#define VEC_quick_insert(T,V,I,O) \
305
        (VEC_OP(T,quick_insert)(V,I,O VEC_ASSERT_INFO))
306
 
307
/* Insert object with reallocation
308
   T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
309
   T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
310
   T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
311
 
312
   Insert an element, VAL, at the IXth position of V. Return a pointer
313
   to the slot created.  For vectors of object, the new value can be
314
   NULL, in which case no initialization of the inserted slot takes
315
   place. Reallocate V, if necessary.  */
316
 
317
#define VEC_safe_insert(T,V,I,O)        \
318
        (VEC_OP(T,safe_insert)(&(V),I,O VEC_ASSERT_INFO))
319
 
320
/* Remove element retaining order
321
   T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
322
   T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
323
   void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
324
 
325
   Remove an element from the IXth position of V. Ordering of
326
   remaining elements is preserved.  For pointer vectors returns the
327
   removed object.  This is an O(N) operation due to a memmove.  */
328
 
329
#define VEC_ordered_remove(T,V,I)       \
330
        (VEC_OP(T,ordered_remove)(V,I VEC_ASSERT_INFO))
331
 
332
/* Remove element destroying order
333
   T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
334
   T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
335
   void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
336
 
337
   Remove an element from the IXth position of V. Ordering of
338
   remaining elements is destroyed.  For pointer vectors returns the
339
   removed object.  This is an O(1) operation.  */
340
 
341
#define VEC_unordered_remove(T,V,I)     \
342
        (VEC_OP(T,unordered_remove)(V,I VEC_ASSERT_INFO))
343
 
344
/* Remove a block of elements
345
   void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
346
 
347
   Remove LEN elements starting at the IXth.  Ordering is retained.
348
   This is an O(1) operation.  */
349
 
350
#define VEC_block_remove(T,V,I,L)       \
351
        (VEC_OP(T,block_remove)(V,I,L) VEC_ASSERT_INFO)
352
 
353
/* Get the address of the array of elements
354
   T *VEC_T_address (VEC(T) v)
355
 
356
   If you need to directly manipulate the array (for instance, you
357
   want to feed it to qsort), use this accessor.  */
358
 
359
#define VEC_address(T,V)                (VEC_OP(T,address)(V))
360
 
361
/* Find the first index in the vector not less than the object.
362
   unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
363
                               int (*lessthan) (const T, const T)); // Integer
364
   unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
365
                               int (*lessthan) (const T, const T)); // Pointer
366
   unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
367
                               int (*lessthan) (const T*, const T*)); // Object
368
 
369
   Find the first position in which VAL could be inserted without
370
   changing the ordering of V.  LESSTHAN is a function that returns
371
   true if the first argument is strictly less than the second.  */
372
 
373
#define VEC_lower_bound(T,V,O,LT)    \
374
       (VEC_OP(T,lower_bound)(V,O,LT VEC_ASSERT_INFO))
375
 
376
/* Reallocate an array of elements with prefix.  */
377
extern void *vec_p_reserve (void *, int);
378
extern void *vec_o_reserve (void *, int, size_t, size_t);
379
#define vec_free_(V) xfree (V)
380
 
381
#define VEC_ASSERT_INFO ,__FILE__,__LINE__
382
#define VEC_ASSERT_DECL ,const char *file_,unsigned line_
383
#define VEC_ASSERT_PASS ,file_,line_
384
#define vec_assert(expr, op) \
385
  ((void)((expr) ? 0 : (gdb_assert_fail (op, file_, line_, ASSERT_FUNCTION), 0)))
386
 
387
#define VEC(T) VEC_##T
388
#define VEC_OP(T,OP) VEC_##T##_##OP
389
 
390
#define VEC_T(T)                                                          \
391
typedef struct VEC(T)                                                     \
392
{                                                                         \
393
  unsigned num;                                                           \
394
  unsigned alloc;                                                         \
395
  T vec[1];                                                               \
396
} VEC(T)
397
 
398
/* Vector of integer-like object.  */
399
#define DEF_VEC_I(T)                                                      \
400
static inline void VEC_OP (T,must_be_integral_type) (void)                \
401
{                                                                         \
402
  (void)~(T)0;                                                             \
403
}                                                                         \
404
                                                                          \
405
VEC_T(T);                                                                 \
406
DEF_VEC_FUNC_P(T)                                                         \
407
DEF_VEC_ALLOC_FUNC_I(T)                                                   \
408
struct vec_swallow_trailing_semi
409
 
410
/* Vector of pointer to object.  */
411
#define DEF_VEC_P(T)                                                      \
412
static inline void VEC_OP (T,must_be_pointer_type) (void)                 \
413
{                                                                         \
414
  (void)((T)1 == (void *)1);                                              \
415
}                                                                         \
416
                                                                          \
417
VEC_T(T);                                                                 \
418
DEF_VEC_FUNC_P(T)                                                         \
419
DEF_VEC_ALLOC_FUNC_P(T)                                                   \
420
struct vec_swallow_trailing_semi
421
 
422
/* Vector of object.  */
423
#define DEF_VEC_O(T)                                                      \
424
VEC_T(T);                                                                 \
425
DEF_VEC_FUNC_O(T)                                                         \
426
DEF_VEC_ALLOC_FUNC_O(T)                                                   \
427
struct vec_swallow_trailing_semi
428
 
429
#define DEF_VEC_ALLOC_FUNC_I(T)                                           \
430
static inline VEC(T) *VEC_OP (T,alloc)                                    \
431
     (int alloc_)                                                         \
432
{                                                                         \
433
  /* We must request exact size allocation, hence the negation.  */       \
434
  return (VEC(T) *) vec_o_reserve (NULL, -alloc_,                         \
435
                                   offsetof (VEC(T),vec), sizeof (T));    \
436
}                                                                         \
437
                                                                          \
438
static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                      \
439
{                                                                         \
440
  size_t len_ = vec_ ? vec_->num : 0;                                      \
441
  VEC (T) *new_vec_ = NULL;                                               \
442
                                                                          \
443
  if (len_)                                                               \
444
    {                                                                     \
445
      /* We must request exact size allocation, hence the negation. */    \
446
      new_vec_ = (VEC (T) *)                                              \
447
        vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));   \
448
                                                                          \
449
      new_vec_->num = len_;                                               \
450
      memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_);               \
451
    }                                                                     \
452
  return new_vec_;                                                        \
453
}                                                                         \
454
                                                                          \
455
static inline void VEC_OP (T,free)                                        \
456
     (VEC(T) **vec_)                                                      \
457
{                                                                         \
458
  if (*vec_)                                                              \
459
    vec_free_ (*vec_);                                                    \
460
  *vec_ = NULL;                                                           \
461
}                                                                         \
462
                                                                          \
463
static inline int VEC_OP (T,reserve)                                      \
464
     (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL)                          \
465
{                                                                         \
466
  int extend = !VEC_OP (T,space)                                          \
467
        (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS);            \
468
                                                                          \
469
  if (extend)                                                             \
470
    *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_,                      \
471
                                      offsetof (VEC(T),vec), sizeof (T)); \
472
                                                                          \
473
  return extend;                                                          \
474
}                                                                         \
475
                                                                          \
476
static inline void VEC_OP (T,safe_grow)                                   \
477
     (VEC(T) **vec_, int size_ VEC_ASSERT_DECL)                           \
478
{                                                                         \
479
  vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_,  \
480
        "safe_grow");                                                     \
481
  VEC_OP (T,reserve) (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_        \
482
                        VEC_ASSERT_PASS);                                 \
483
  (*vec_)->num = size_;                                                   \
484
}                                                                         \
485
                                                                          \
486
static inline T *VEC_OP (T,safe_push)                                     \
487
     (VEC(T) **vec_, const T obj_ VEC_ASSERT_DECL)                        \
488
{                                                                         \
489
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
490
                                                                          \
491
  return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS);             \
492
}                                                                         \
493
                                                                          \
494
static inline T *VEC_OP (T,safe_insert)                                   \
495
     (VEC(T) **vec_, unsigned ix_, const T obj_ VEC_ASSERT_DECL)          \
496
{                                                                         \
497
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
498
                                                                          \
499
  return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS);      \
500
}
501
 
502
#define DEF_VEC_FUNC_P(T)                                                 \
503
static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_)             \
504
{                                                                         \
505
  return vec_ ? vec_->num : 0;                                             \
506
}                                                                         \
507
                                                                          \
508
static inline T VEC_OP (T,last)                                           \
509
        (const VEC(T) *vec_ VEC_ASSERT_DECL)                              \
510
{                                                                         \
511
  vec_assert (vec_ && vec_->num, "last");                                 \
512
                                                                          \
513
  return vec_->vec[vec_->num - 1];                                        \
514
}                                                                         \
515
                                                                          \
516
static inline T VEC_OP (T,index)                                          \
517
     (const VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                   \
518
{                                                                         \
519
  vec_assert (vec_ && ix_ < vec_->num, "index");                          \
520
                                                                          \
521
  return vec_->vec[ix_];                                                  \
522
}                                                                         \
523
                                                                          \
524
static inline int VEC_OP (T,iterate)                                      \
525
     (const VEC(T) *vec_, unsigned ix_, T *ptr)                           \
526
{                                                                         \
527
  if (vec_ && ix_ < vec_->num)                                            \
528
    {                                                                     \
529
      *ptr = vec_->vec[ix_];                                              \
530
      return 1;                                                           \
531
    }                                                                     \
532
  else                                                                    \
533
    {                                                                     \
534
      *ptr = 0;                                                            \
535
      return 0;                                                            \
536
    }                                                                     \
537
}                                                                         \
538
                                                                          \
539
static inline size_t VEC_OP (T,embedded_size)                             \
540
     (int alloc_)                                                         \
541
{                                                                         \
542
  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);                      \
543
}                                                                         \
544
                                                                          \
545
static inline void VEC_OP (T,embedded_init)                               \
546
     (VEC(T) *vec_, int alloc_)                                           \
547
{                                                                         \
548
  vec_->num = 0;                                                   \
549
  vec_->alloc = alloc_;                                                   \
550
}                                                                         \
551
                                                                          \
552
static inline int VEC_OP (T,space)                                        \
553
     (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL)                           \
554
{                                                                         \
555
  vec_assert (alloc_ >= 0, "space");                                       \
556
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;    \
557
}                                                                         \
558
                                                                          \
559
static inline T *VEC_OP (T,quick_push)                                    \
560
     (VEC(T) *vec_, T obj_ VEC_ASSERT_DECL)                               \
561
{                                                                         \
562
  T *slot_;                                                               \
563
                                                                          \
564
  vec_assert (vec_->num < vec_->alloc, "quick_push");                     \
565
  slot_ = &vec_->vec[vec_->num++];                                        \
566
  *slot_ = obj_;                                                          \
567
                                                                          \
568
  return slot_;                                                           \
569
}                                                                         \
570
                                                                          \
571
static inline T VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL)             \
572
{                                                                         \
573
  T obj_;                                                                 \
574
                                                                          \
575
  vec_assert (vec_->num, "pop");                                          \
576
  obj_ = vec_->vec[--vec_->num];                                          \
577
                                                                          \
578
  return obj_;                                                            \
579
}                                                                         \
580
                                                                          \
581
static inline void VEC_OP (T,truncate)                                    \
582
     (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL)                       \
583
{                                                                         \
584
  vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate");            \
585
  if (vec_)                                                               \
586
    vec_->num = size_;                                                    \
587
}                                                                         \
588
                                                                          \
589
static inline T VEC_OP (T,replace)                                        \
590
     (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL)                 \
591
{                                                                         \
592
  T old_obj_;                                                             \
593
                                                                          \
594
  vec_assert (ix_ < vec_->num, "replace");                                \
595
  old_obj_ = vec_->vec[ix_];                                              \
596
  vec_->vec[ix_] = obj_;                                                  \
597
                                                                          \
598
  return old_obj_;                                                        \
599
}                                                                         \
600
                                                                          \
601
static inline T *VEC_OP (T,quick_insert)                                  \
602
     (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL)                 \
603
{                                                                         \
604
  T *slot_;                                                               \
605
                                                                          \
606
  vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
607
  slot_ = &vec_->vec[ix_];                                                \
608
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));           \
609
  *slot_ = obj_;                                                          \
610
                                                                          \
611
  return slot_;                                                           \
612
}                                                                         \
613
                                                                          \
614
static inline T VEC_OP (T,ordered_remove)                                 \
615
     (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                         \
616
{                                                                         \
617
  T *slot_;                                                               \
618
  T obj_;                                                                 \
619
                                                                          \
620
  vec_assert (ix_ < vec_->num, "ordered_remove");                         \
621
  slot_ = &vec_->vec[ix_];                                                \
622
  obj_ = *slot_;                                                          \
623
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));           \
624
                                                                          \
625
  return obj_;                                                            \
626
}                                                                         \
627
                                                                          \
628
static inline T VEC_OP (T,unordered_remove)                               \
629
     (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                         \
630
{                                                                         \
631
  T *slot_;                                                               \
632
  T obj_;                                                                 \
633
                                                                          \
634
  vec_assert (ix_ < vec_->num, "unordered_remove");                       \
635
  slot_ = &vec_->vec[ix_];                                                \
636
  obj_ = *slot_;                                                          \
637
  *slot_ = vec_->vec[--vec_->num];                                        \
638
                                                                          \
639
  return obj_;                                                            \
640
}                                                                         \
641
                                                                          \
642
static inline void VEC_OP (T,block_remove)                                \
643
     (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL)          \
644
{                                                                         \
645
  T *slot_;                                                               \
646
                                                                          \
647
  vec_assert (ix_ + len_ <= vec_->num, "block_remove");                   \
648
  slot_ = &vec_->vec[ix_];                                                \
649
  vec_->num -= len_;                                                      \
650
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));          \
651
}                                                                         \
652
                                                                          \
653
static inline T *VEC_OP (T,address)                                       \
654
     (VEC(T) *vec_)                                                       \
655
{                                                                         \
656
  return vec_ ? vec_->vec : 0;                                             \
657
}                                                                         \
658
                                                                          \
659
static inline unsigned VEC_OP (T,lower_bound)                             \
660
     (VEC(T) *vec_, const T obj_,                                         \
661
      int (*lessthan_)(const T, const T) VEC_ASSERT_DECL)                 \
662
{                                                                         \
663
   unsigned int len_ = VEC_OP (T, length) (vec_);                         \
664
   unsigned int half_, middle_;                                           \
665
   unsigned int first_ = 0;                                                \
666
   while (len_ > 0)                                                        \
667
     {                                                                    \
668
        T middle_elem_;                                                   \
669
        half_ = len_ >> 1;                                                \
670
        middle_ = first_;                                                 \
671
        middle_ += half_;                                                 \
672
        middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS);  \
673
        if (lessthan_ (middle_elem_, obj_))                               \
674
          {                                                               \
675
             first_ = middle_;                                            \
676
             ++first_;                                                    \
677
             len_ = len_ - half_ - 1;                                     \
678
          }                                                               \
679
        else                                                              \
680
          len_ = half_;                                                   \
681
     }                                                                    \
682
   return first_;                                                         \
683
}
684
 
685
#define DEF_VEC_ALLOC_FUNC_P(T)                                           \
686
static inline VEC(T) *VEC_OP (T,alloc)                                    \
687
     (int alloc_)                                                         \
688
{                                                                         \
689
  /* We must request exact size allocation, hence the negation.  */       \
690
  return (VEC(T) *) vec_p_reserve (NULL, -alloc_);                        \
691
}                                                                         \
692
                                                                          \
693
static inline void VEC_OP (T,free)                                        \
694
     (VEC(T) **vec_)                                                      \
695
{                                                                         \
696
  if (*vec_)                                                              \
697
    vec_free_ (*vec_);                                                    \
698
  *vec_ = NULL;                                                           \
699
}                                                                         \
700
                                                                          \
701
static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                      \
702
{                                                                         \
703
  size_t len_ = vec_ ? vec_->num : 0;                                      \
704
  VEC (T) *new_vec_ = NULL;                                               \
705
                                                                          \
706
  if (len_)                                                               \
707
    {                                                                     \
708
      /* We must request exact size allocation, hence the negation. */    \
709
      new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_));                \
710
                                                                          \
711
      new_vec_->num = len_;                                               \
712
      memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_);               \
713
    }                                                                     \
714
  return new_vec_;                                                        \
715
}                                                                         \
716
                                                                          \
717
static inline int VEC_OP (T,reserve)                                      \
718
     (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL)                          \
719
{                                                                         \
720
  int extend = !VEC_OP (T,space)                                          \
721
        (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS);            \
722
                                                                          \
723
  if (extend)                                                             \
724
    *vec_ = (VEC(T) *) vec_p_reserve (*vec_, alloc_);                     \
725
                                                                          \
726
  return extend;                                                          \
727
}                                                                         \
728
                                                                          \
729
static inline void VEC_OP (T,safe_grow)                                   \
730
     (VEC(T) **vec_, int size_ VEC_ASSERT_DECL)                           \
731
{                                                                         \
732
  vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_,  \
733
        "safe_grow");                                                     \
734
  VEC_OP (T,reserve)                                                      \
735
        (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS);  \
736
  (*vec_)->num = size_;                                                   \
737
}                                                                         \
738
                                                                          \
739
static inline T *VEC_OP (T,safe_push)                                     \
740
     (VEC(T) **vec_, T obj_ VEC_ASSERT_DECL)                              \
741
{                                                                         \
742
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
743
                                                                          \
744
  return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS);             \
745
}                                                                         \
746
                                                                          \
747
static inline T *VEC_OP (T,safe_insert)                                   \
748
     (VEC(T) **vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL)                \
749
{                                                                         \
750
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
751
                                                                          \
752
  return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS);      \
753
}
754
 
755
#define DEF_VEC_FUNC_O(T)                                                 \
756
static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_)             \
757
{                                                                         \
758
  return vec_ ? vec_->num : 0;                                             \
759
}                                                                         \
760
                                                                          \
761
static inline T *VEC_OP (T,last) (VEC(T) *vec_ VEC_ASSERT_DECL)           \
762
{                                                                         \
763
  vec_assert (vec_ && vec_->num, "last");                                 \
764
                                                                          \
765
  return &vec_->vec[vec_->num - 1];                                       \
766
}                                                                         \
767
                                                                          \
768
static inline T *VEC_OP (T,index)                                         \
769
     (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                         \
770
{                                                                         \
771
  vec_assert (vec_ && ix_ < vec_->num, "index");                          \
772
                                                                          \
773
  return &vec_->vec[ix_];                                                 \
774
}                                                                         \
775
                                                                          \
776
static inline int VEC_OP (T,iterate)                                      \
777
     (VEC(T) *vec_, unsigned ix_, T **ptr)                                \
778
{                                                                         \
779
  if (vec_ && ix_ < vec_->num)                                            \
780
    {                                                                     \
781
      *ptr = &vec_->vec[ix_];                                             \
782
      return 1;                                                           \
783
    }                                                                     \
784
  else                                                                    \
785
    {                                                                     \
786
      *ptr = 0;                                                            \
787
      return 0;                                                            \
788
    }                                                                     \
789
}                                                                         \
790
                                                                          \
791
static inline size_t VEC_OP (T,embedded_size)                             \
792
     (int alloc_)                                                         \
793
{                                                                         \
794
  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);                      \
795
}                                                                         \
796
                                                                          \
797
static inline void VEC_OP (T,embedded_init)                               \
798
     (VEC(T) *vec_, int alloc_)                                           \
799
{                                                                         \
800
  vec_->num = 0;                                                   \
801
  vec_->alloc = alloc_;                                                   \
802
}                                                                         \
803
                                                                          \
804
static inline int VEC_OP (T,space)                                        \
805
     (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL)                           \
806
{                                                                         \
807
  vec_assert (alloc_ >= 0, "space");                                       \
808
  return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_;    \
809
}                                                                         \
810
                                                                          \
811
static inline T *VEC_OP (T,quick_push)                                    \
812
     (VEC(T) *vec_, const T *obj_ VEC_ASSERT_DECL)                        \
813
{                                                                         \
814
  T *slot_;                                                               \
815
                                                                          \
816
  vec_assert (vec_->num < vec_->alloc, "quick_push");                     \
817
  slot_ = &vec_->vec[vec_->num++];                                        \
818
  if (obj_)                                                               \
819
    *slot_ = *obj_;                                                       \
820
                                                                          \
821
  return slot_;                                                           \
822
}                                                                         \
823
                                                                          \
824
static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL)          \
825
{                                                                         \
826
  vec_assert (vec_->num, "pop");                                          \
827
  --vec_->num;                                                            \
828
}                                                                         \
829
                                                                          \
830
static inline void VEC_OP (T,truncate)                                    \
831
     (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL)                       \
832
{                                                                         \
833
  vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate");            \
834
  if (vec_)                                                               \
835
    vec_->num = size_;                                                    \
836
}                                                                         \
837
                                                                          \
838
static inline T *VEC_OP (T,replace)                                       \
839
     (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL)          \
840
{                                                                         \
841
  T *slot_;                                                               \
842
                                                                          \
843
  vec_assert (ix_ < vec_->num, "replace");                                \
844
  slot_ = &vec_->vec[ix_];                                                \
845
  if (obj_)                                                               \
846
    *slot_ = *obj_;                                                       \
847
                                                                          \
848
  return slot_;                                                           \
849
}                                                                         \
850
                                                                          \
851
static inline T *VEC_OP (T,quick_insert)                                  \
852
     (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL)          \
853
{                                                                         \
854
  T *slot_;                                                               \
855
                                                                          \
856
  vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
857
  slot_ = &vec_->vec[ix_];                                                \
858
  memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T));           \
859
  if (obj_)                                                               \
860
    *slot_ = *obj_;                                                       \
861
                                                                          \
862
  return slot_;                                                           \
863
}                                                                         \
864
                                                                          \
865
static inline void VEC_OP (T,ordered_remove)                              \
866
     (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                         \
867
{                                                                         \
868
  T *slot_;                                                               \
869
                                                                          \
870
  vec_assert (ix_ < vec_->num, "ordered_remove");                         \
871
  slot_ = &vec_->vec[ix_];                                                \
872
  memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T));           \
873
}                                                                         \
874
                                                                          \
875
static inline void VEC_OP (T,unordered_remove)                            \
876
     (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL)                         \
877
{                                                                         \
878
  vec_assert (ix_ < vec_->num, "unordered_remove");                       \
879
  vec_->vec[ix_] = vec_->vec[--vec_->num];                                \
880
}                                                                         \
881
                                                                          \
882
static inline void VEC_OP (T,block_remove)                                \
883
     (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL)          \
884
{                                                                         \
885
  T *slot_;                                                               \
886
                                                                          \
887
  vec_assert (ix_ + len_ <= vec_->num, "block_remove");                   \
888
  slot_ = &vec_->vec[ix_];                                                \
889
  vec_->num -= len_;                                                      \
890
  memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T));          \
891
}                                                                         \
892
                                                                          \
893
static inline T *VEC_OP (T,address)                                       \
894
     (VEC(T) *vec_)                                                       \
895
{                                                                         \
896
  return vec_ ? vec_->vec : 0;                                             \
897
}                                                                         \
898
                                                                          \
899
static inline unsigned VEC_OP (T,lower_bound)                             \
900
     (VEC(T) *vec_, const T *obj_,                                        \
901
      int (*lessthan_)(const T *, const T *) VEC_ASSERT_DECL)             \
902
{                                                                         \
903
   unsigned int len_ = VEC_OP (T, length) (vec_);                         \
904
   unsigned int half_, middle_;                                           \
905
   unsigned int first_ = 0;                                                \
906
   while (len_ > 0)                                                        \
907
     {                                                                    \
908
        T *middle_elem_;                                                  \
909
        half_ = len_ >> 1;                                                \
910
        middle_ = first_;                                                 \
911
        middle_ += half_;                                                 \
912
        middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS);  \
913
        if (lessthan_ (middle_elem_, obj_))                               \
914
          {                                                               \
915
             first_ = middle_;                                            \
916
             ++first_;                                                    \
917
             len_ = len_ - half_ - 1;                                     \
918
          }                                                               \
919
        else                                                              \
920
          len_ = half_;                                                   \
921
     }                                                                    \
922
   return first_;                                                         \
923
}
924
 
925
#define DEF_VEC_ALLOC_FUNC_O(T)                                           \
926
static inline VEC(T) *VEC_OP (T,alloc)                                    \
927
     (int alloc_)                                                         \
928
{                                                                         \
929
  /* We must request exact size allocation, hence the negation.  */       \
930
  return (VEC(T) *) vec_o_reserve (NULL, -alloc_,                         \
931
                                   offsetof (VEC(T),vec), sizeof (T));    \
932
}                                                                         \
933
                                                                          \
934
static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                      \
935
{                                                                         \
936
  size_t len_ = vec_ ? vec_->num : 0;                                      \
937
  VEC (T) *new_vec_ = NULL;                                               \
938
                                                                          \
939
  if (len_)                                                               \
940
    {                                                                     \
941
      /* We must request exact size allocation, hence the negation. */    \
942
      new_vec_ = (VEC (T) *)                                              \
943
        vec_o_reserve  (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));  \
944
                                                                          \
945
      new_vec_->num = len_;                                               \
946
      memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_);               \
947
    }                                                                     \
948
  return new_vec_;                                                        \
949
}                                                                         \
950
                                                                          \
951
static inline void VEC_OP (T,free)                                        \
952
     (VEC(T) **vec_)                                                      \
953
{                                                                         \
954
  if (*vec_)                                                              \
955
    vec_free_ (*vec_);                                                    \
956
  *vec_ = NULL;                                                           \
957
}                                                                         \
958
                                                                          \
959
static inline int VEC_OP (T,reserve)                                      \
960
     (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL)                          \
961
{                                                                         \
962
  int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_     \
963
                                  VEC_ASSERT_PASS);                       \
964
                                                                          \
965
  if (extend)                                                             \
966
    *vec_ = (VEC(T) *)                                                    \
967
        vec_o_reserve (*vec_, alloc_, offsetof (VEC(T),vec), sizeof (T)); \
968
                                                                          \
969
  return extend;                                                          \
970
}                                                                         \
971
                                                                          \
972
static inline void VEC_OP (T,safe_grow)                                   \
973
     (VEC(T) **vec_, int size_ VEC_ASSERT_DECL)                           \
974
{                                                                         \
975
  vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_,  \
976
        "safe_grow");                                                     \
977
  VEC_OP (T,reserve)                                                      \
978
        (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS);  \
979
  (*vec_)->num = size_;                                                   \
980
}                                                                         \
981
                                                                          \
982
static inline T *VEC_OP (T,safe_push)                                     \
983
     (VEC(T) **vec_, const T *obj_ VEC_ASSERT_DECL)                       \
984
{                                                                         \
985
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
986
                                                                          \
987
  return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS);             \
988
}                                                                         \
989
                                                                          \
990
static inline T *VEC_OP (T,safe_insert)                                   \
991
     (VEC(T) **vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL)         \
992
{                                                                         \
993
  VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS);                           \
994
                                                                          \
995
  return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS);      \
996
}
997
 
998
#endif /* GDB_VEC_H */

powered by: WebSVN 2.1.0

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