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