You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#ifndef GCC_VEC_H
#define GCC_VEC_H
out-of-line generic functions. The vectors are designed to
interoperate with the GTY machinery.
- Because of the different behavior of objects and of pointers to
- objects, there are two flavors. One to deal with a vector of
- pointers to objects, and one to deal with a vector of objects
- themselves. Both of these pass pointers to objects around -- in
- the former case the pointers are stored into the vector and in the
- latter case the pointers are dereferenced and the objects copied
- into the vector. Therefore, when using a vector of pointers, the
- objects pointed to must be long lived, but when dealing with a
- vector of objects, the source objects need not be. The vector of
- pointers API is also appropriate for small register sized objects
- like integers.
+ Because of the different behavior of structure objects, scalar
+ objects and of pointers, there are three flavors, one for each of
+ these variants. Both the structure object and pointer variants
+ pass pointers to objects around -- in the former case the pointers
+ are stored into the vector and in the latter case the pointers are
+ dereferenced and the objects copied into the vector. The scalar
+ object variant is suitable for int-like objects, and the vector
+ elements are returned by value.
There are both 'index' and 'iterate' accessors. The iterator
returns a boolean iteration condition and updates the iteration
the 'space' predicate will tell you whether there is spare capacity
in the vector. You will not normally need to use these two functions.
- Vector types are defined using a DEF_VEC_{O,P}(TYPEDEF) macro, to
+ Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
get the non-memory allocation version, and then a
- DEF_VEC_ALLOC_{O,P}(TYPEDEF,ALLOC) macro to get memory managed
+ DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
vectors. Variables of vector type are declared using a
VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the
allocation strategy, and can be either 'gc' or 'heap' for garbage
collected and heap allocated respectively. It can be 'none' to get
a vector that must be explicitly allocated (for instance as a
- trailing array of another structure). The characters O and P
- indicate whether TYPEDEF is a pointer (P) or object (O) type. Be
- careful to pick the correct one, as you'll get an awkward and
- inefficient API if you get the wrong one. There is a check, which
- results in a compile-time warning, for the P versions, but there is
- no check for the O versions, as that is not possible in plain C.
+ trailing array of another structure). The characters O, P and I
+ indicate whether TYPEDEF is a pointer (P), object (O) or integral
+ (I) type. Be careful to pick the correct one, as you'll get an
+ awkward and inefficient API if you use the wrong one. There is a
+ check, which results in a compile-time warning, for the P and I
+ versions, but there is no check for the O versions, as that is not
+ possible in plain C. Due to the way GTY works, you must annotate
+ any structures you wish to insert or reference from a vector with a
+ GTY(()) tag. You need to do this even if you never declare the GC
+ allocated variants.
An example of their use would be,
#define VEC_length(T,V) (VEC_OP(T,base,length)(VEC_BASE(V)))
/* Get the final element of the vector.
+ T VEC_T_last(VEC(T) *v); // Integer
T VEC_T_last(VEC(T) *v); // Pointer
T *VEC_T_last(VEC(T) *v); // Object
#define VEC_last(T,V) (VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
/* Index into vector
+ T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
#define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Iterate over vector
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Push object with no reallocation
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
(VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
/* Push object with reallocation
+ T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
(VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
/* Pop element off end
+ T VEC_T_pop (VEC(T) *v); // Integer
T VEC_T_pop (VEC(T) *v); // Pointer
void VEC_T_pop (VEC(T) *v); // Object
uninitialized. */
#define VEC_safe_grow(T,A,V,I) \
- (VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO))
+ (VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))
/* Replace element
+ T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
(VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with no reallocation
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
(VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with reallocation
+ T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
(VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
/* Remove element retaining order
+ T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
(VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Remove element destroying order
+ T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
/* Find the first index in the vector not less than the object.
unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
+ bool (*lessthan) (const T, const T)); // Integer
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
bool (*lessthan) (const T, const T)); // Pointer
unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
bool (*lessthan) (const T*, const T*)); // Object
/* Base of vector type, not user visible. */
#define VEC_T(T,B) \
+typedef struct VEC(T,B) \
+{ \
+ unsigned num; \
+ unsigned alloc; \
+ T vec[1]; \
+} VEC(T,B)
+
+#define VEC_T_GTY(T,B) \
typedef struct VEC(T,B) GTY(()) \
{ \
unsigned num; \
} VEC(T,B)
/* Derived vector type, user visible. */
-#define VEC_TA(T,B,A,GTY) \
+#define VEC_TA_GTY(T,B,A,GTY) \
typedef struct VEC(T,A) GTY \
{ \
VEC(T,B) base; \
/* Convert to base type. */
#define VEC_BASE(P) ((P) ? &(P)->base : 0)
+/* Vector of integer-like object. */
+#if IN_GENGTYPE
+{"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
+#else
+#define DEF_VEC_I(T) \
+static inline void VEC_OP (T,must_be,integral_type) (void) \
+{ \
+ (void)~(T)0; \
+} \
+ \
+VEC_T(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_P(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_I(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_P(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
/* Vector of pointer to object. */
#if IN_GENGTYPE
-{"DEF_VEC_P", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
+{"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_P(T) \
-VEC_T(T,base); \
- \
-static inline void VEC_OP (T,must,be_a_pointer_or_integer) (void) \
+static inline void VEC_OP (T,must_be,pointer_type) (void) \
{ \
- (void)((T)0 == (void *)0); \
+ (void)((T)1 == (void *)1); \
} \
\
+VEC_T_GTY(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_P(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_P(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_P(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
+#define DEF_VEC_FUNC_P(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
len_ = half_; \
} \
return first_; \
-} \
- \
-VEC_TA(T,base,none,)
-
-#define DEF_VEC_ALLOC_P(T,A) \
-VEC_TA(T,base,A,); \
- \
+}
+
+#define DEF_VEC_ALLOC_FUNC_P(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
-} \
- \
-struct vec_swallow_trailing_semi
-#endif
+}
/* Vector of object. */
#if IN_GENGTYPE
-{"DEF_VEC_O", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA(#0,#1,#2,#3)) ";", NULL},
+{"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_O(T) \
-VEC_T(T,base); \
- \
+VEC_T_GTY(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_O(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_O(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_O(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
+#define DEF_VEC_FUNC_O(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
len_ = half_; \
} \
return first_; \
-} \
- \
-VEC_TA(T,base,none,)
+}
-#define DEF_VEC_ALLOC_O(T,A) \
-VEC_TA(T,base,A,); \
- \
+#define DEF_VEC_ALLOC_FUNC_O(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
-} \
- \
-struct vec_swallow_trailing_semi
-#endif
-
+}
#endif /* GCC_VEC_H */