vec.h (VEC_reserve_exact): Define.
./: * vec.h (VEC_reserve_exact): Define. (vec_gc_p_reserve_exact): Declare. (vec_gc_o_reserve_exact): Declare. (vec_heap_p_reserve_exact): Declare. (vec_heap_o_reserve_exact): Declare. (VEC_OP (T,A,reserve_exact)): New static inline function, three versions. (VEC_OP (T,A,reserve)) [all versions]: Remove handling of negative parameter. (VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact. (VEC_OP (T,A,copy)) [all versions]: Likewise. (VEC_OP (T,a,safe_grow)) [all versions]: Likewise. * vec.c (calculate_allocation): Add exact parameter. Change all callers. (vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve. (vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1. (vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions. (vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve. (vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1. (vec_heap_p_reserve_exact): New function. (vec_heap_o_reserve_exact): New function. cp/: * class.c (add_method): Call VEC_reserve_exact rather than passing a negative size to VEC_reserve. From-SVN: r120861
This commit is contained in:
parent
9dd8004e91
commit
efb7e1e026
5 changed files with 237 additions and 76 deletions
|
@ -1,3 +1,27 @@
|
|||
2007-01-17 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* vec.h (VEC_reserve_exact): Define.
|
||||
(vec_gc_p_reserve_exact): Declare.
|
||||
(vec_gc_o_reserve_exact): Declare.
|
||||
(vec_heap_p_reserve_exact): Declare.
|
||||
(vec_heap_o_reserve_exact): Declare.
|
||||
(VEC_OP (T,A,reserve_exact)): New static inline function, three
|
||||
versions.
|
||||
(VEC_OP (T,A,reserve)) [all versions]: Remove handling of
|
||||
negative parameter.
|
||||
(VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact.
|
||||
(VEC_OP (T,A,copy)) [all versions]: Likewise.
|
||||
(VEC_OP (T,a,safe_grow)) [all versions]: Likewise.
|
||||
* vec.c (calculate_allocation): Add exact parameter. Change all
|
||||
callers.
|
||||
(vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve.
|
||||
(vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1.
|
||||
(vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions.
|
||||
(vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve.
|
||||
(vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1.
|
||||
(vec_heap_p_reserve_exact): New function.
|
||||
(vec_heap_o_reserve_exact): New function.
|
||||
|
||||
2007-01-17 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ipa-type-escape.c (look_for_casts): Revamp using handled_component_p.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2007-01-17 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* class.c (add_method): Call VEC_reserve_exact rather than passing
|
||||
a negative size to VEC_reserve.
|
||||
|
||||
2007-01-11 Simon Martin <simartin@users.sourceforge.net>
|
||||
|
||||
PR c++/29573
|
||||
|
|
|
@ -1071,9 +1071,15 @@ add_method (tree type, tree method, tree using_decl)
|
|||
|
||||
if (insert_p)
|
||||
{
|
||||
bool reallocated;
|
||||
|
||||
/* We only expect to add few methods in the COMPLETE_P case, so
|
||||
just make room for one more method in that case. */
|
||||
if (VEC_reserve (tree, gc, method_vec, complete_p ? -1 : 1))
|
||||
if (complete_p)
|
||||
reallocated = VEC_reserve_exact (tree, gc, method_vec, 1);
|
||||
else
|
||||
reallocated = VEC_reserve (tree, gc, method_vec, 1);
|
||||
if (reallocated)
|
||||
CLASSTYPE_METHOD_VEC (type) = method_vec;
|
||||
if (slot == VEC_length (tree, method_vec))
|
||||
VEC_quick_push (tree, method_vec, overload);
|
||||
|
|
143
gcc/vec.c
143
gcc/vec.c
|
@ -40,16 +40,17 @@ struct vec_prefix
|
|||
void *vec[1];
|
||||
};
|
||||
|
||||
/* Calculate the new ALLOC value, making sure that abs(RESERVE) slots
|
||||
are free. If RESERVE < 0 grow exactly, otherwise grow
|
||||
exponentially. */
|
||||
/* Calculate the new ALLOC value, making sure that RESERVE slots are
|
||||
free. If EXACT grow exactly, otherwise grow exponentially. */
|
||||
|
||||
static inline unsigned
|
||||
calculate_allocation (const struct vec_prefix *pfx, int reserve)
|
||||
calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact)
|
||||
{
|
||||
unsigned alloc = 0;
|
||||
unsigned num = 0;
|
||||
|
||||
gcc_assert (reserve >= 0);
|
||||
|
||||
if (pfx)
|
||||
{
|
||||
alloc = pfx->alloc;
|
||||
|
@ -61,11 +62,11 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
|
|||
return 0;
|
||||
|
||||
/* We must have run out of room. */
|
||||
gcc_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve));
|
||||
gcc_assert (alloc - num < (unsigned) reserve);
|
||||
|
||||
if (reserve < 0)
|
||||
if (exact)
|
||||
/* Exact size. */
|
||||
alloc = num + -reserve;
|
||||
alloc = num + reserve;
|
||||
else
|
||||
{
|
||||
/* Exponential growth. */
|
||||
|
@ -85,28 +86,18 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
|
|||
return alloc;
|
||||
}
|
||||
|
||||
/* Ensure there are at least abs(RESERVE) free slots in VEC. If
|
||||
RESERVE < 0 grow exactly, else grow exponentially. As a special
|
||||
case, if VEC is NULL, and RESERVE is 0, no vector will be created. */
|
||||
/* Ensure there are at least RESERVE free slots in VEC. If EXACT grow
|
||||
exactly, else grow exponentially. As a special case, if VEC is
|
||||
NULL and RESERVE is 0, no vector will be created. The vector's
|
||||
trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
|
||||
sized elements. */
|
||||
|
||||
void *
|
||||
vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
|
||||
{
|
||||
return vec_gc_o_reserve (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec), sizeof (void *)
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As vec_gc_p_reserve, but for object vectors. The vector's trailing
|
||||
array is at VEC_OFFSET offset and consists of ELT_SIZE sized
|
||||
elements. */
|
||||
|
||||
void *
|
||||
vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
||||
MEM_STAT_DECL)
|
||||
static void *
|
||||
vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
|
||||
bool exact MEM_STAT_DECL)
|
||||
{
|
||||
struct vec_prefix *pfx = vec;
|
||||
unsigned alloc = alloc = calculate_allocation (pfx, reserve);
|
||||
unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
|
||||
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
@ -119,24 +110,66 @@ vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
|||
return vec;
|
||||
}
|
||||
|
||||
/* As for vec_gc_p_reserve, but for heap allocated vectors. */
|
||||
/* Ensure there are at least RESERVE free slots in VEC, growing
|
||||
exponentially. If RESERVE < 0 grow exactly, else grow
|
||||
exponentially. As a special case, if VEC is NULL, and RESERVE is
|
||||
0, no vector will be created. */
|
||||
|
||||
void *
|
||||
vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
|
||||
vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
|
||||
{
|
||||
return vec_heap_o_reserve (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec), sizeof (void *)
|
||||
return vec_gc_o_reserve_1 (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec),
|
||||
sizeof (void *), false
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_o_reserve, but for heap allocated vectors. */
|
||||
/* Ensure there are at least RESERVE free slots in VEC, growing
|
||||
exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
|
||||
a special case, if VEC is NULL, and RESERVE is 0, no vector will be
|
||||
created. */
|
||||
|
||||
void *
|
||||
vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
||||
MEM_STAT_DECL)
|
||||
vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
|
||||
{
|
||||
return vec_gc_o_reserve_1 (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec),
|
||||
sizeof (void *), true
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_p_reserve, but for object vectors. The vector's
|
||||
trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
|
||||
sized elements. */
|
||||
|
||||
void *
|
||||
vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
||||
MEM_STAT_DECL)
|
||||
{
|
||||
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_p_reserve_exact, but for object vectors. The
|
||||
vector's trailing array is at VEC_OFFSET offset and consists of
|
||||
ELT_SIZE sized elements. */
|
||||
|
||||
void *
|
||||
vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
|
||||
size_t elt_size MEM_STAT_DECL)
|
||||
{
|
||||
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_o_reserve_1, but for heap allocated vectors. */
|
||||
|
||||
static void *
|
||||
vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset,
|
||||
size_t elt_size, bool exact MEM_STAT_DECL)
|
||||
{
|
||||
struct vec_prefix *pfx = vec;
|
||||
unsigned alloc = calculate_allocation (pfx, reserve);
|
||||
unsigned alloc = calculate_allocation (pfx, reserve, exact);
|
||||
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
@ -149,6 +182,48 @@ vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
|||
return vec;
|
||||
}
|
||||
|
||||
/* As for vec_gc_p_reserve, but for heap allocated vectors. */
|
||||
|
||||
void *
|
||||
vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
|
||||
{
|
||||
return vec_heap_o_reserve_1 (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec),
|
||||
sizeof (void *), false
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_p_reserve_exact, but for heap allocated vectors. */
|
||||
|
||||
void *
|
||||
vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
|
||||
{
|
||||
return vec_heap_o_reserve_1 (vec, reserve,
|
||||
offsetof (struct vec_prefix, vec),
|
||||
sizeof (void *), true
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_o_reserve, but for heap allocated vectors. */
|
||||
|
||||
void *
|
||||
vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
|
||||
MEM_STAT_DECL)
|
||||
{
|
||||
return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
/* As for vec_gc_o_reserve_exact, but for heap allocated vectors. */
|
||||
|
||||
void *
|
||||
vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
|
||||
size_t elt_size MEM_STAT_DECL)
|
||||
{
|
||||
return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
|
||||
PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
#if ENABLE_CHECKING
|
||||
/* Issue a vector domain error, and then fall over. */
|
||||
|
||||
|
|
133
gcc/vec.h
133
gcc/vec.h
|
@ -66,8 +66,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||
least as many elements as you ask for, it will exponentially
|
||||
increase if there are too few spare slots. If you want reserve a
|
||||
specific number of slots, but do not want the exponential increase
|
||||
(for instance, you know this is the last allocation), use a
|
||||
negative number for reservation. You can also create a vector of a
|
||||
(for instance, you know this is the last allocation), use the
|
||||
reserve_exact operation. You can also create a vector of a
|
||||
specific size from the get go.
|
||||
|
||||
You should prefer the push and pop operations, as they append and
|
||||
|
@ -238,16 +238,25 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||
/* Reserve space.
|
||||
int VEC_T_A_reserve(VEC(T,A) *&v, int reserve);
|
||||
|
||||
Ensure that V has at least abs(RESERVE) slots available. The
|
||||
signedness of RESERVE determines the reallocation behavior. A
|
||||
negative value will not create additional headroom beyond that
|
||||
requested. A positive value will create additional headroom. Note
|
||||
this can cause V to be reallocated. Returns nonzero iff
|
||||
reallocation actually occurred. */
|
||||
Ensure that V has at least RESERVE slots available. This will
|
||||
create additional headroom. Note this can cause V to be
|
||||
reallocated. Returns nonzero iff reallocation actually
|
||||
occurred. */
|
||||
|
||||
#define VEC_reserve(T,A,V,R) \
|
||||
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
|
||||
|
||||
/* Reserve space exactly.
|
||||
int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve);
|
||||
|
||||
Ensure that V has at least RESERVE slots available. This will not
|
||||
create additional headroom. Note this can cause V to be
|
||||
reallocated. Returns nonzero iff reallocation actually
|
||||
occurred. */
|
||||
|
||||
#define VEC_reserve_exact(T,A,V,R) \
|
||||
(VEC_OP(T,A,reserve_exact)(&(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
|
||||
|
@ -411,11 +420,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||
#if !IN_GENGTYPE
|
||||
/* Reallocate an array of elements with prefix. */
|
||||
extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
|
||||
extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
|
||||
extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
|
||||
extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
|
||||
MEM_STAT_DECL);
|
||||
extern void ggc_free (void *);
|
||||
#define vec_gc_free(V) ggc_free (V)
|
||||
extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
|
||||
extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
|
||||
extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
|
||||
extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
|
||||
MEM_STAT_DECL);
|
||||
#define vec_heap_free(V) free (V)
|
||||
|
||||
#if ENABLE_CHECKING
|
||||
|
@ -702,8 +717,8 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
|
|||
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
|
||||
(int alloc_ MEM_STAT_DECL) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
return (VEC(T,A) *) vec_##A##_p_reserve (NULL, -alloc_ PASS_MEM_STAT); \
|
||||
return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
|
||||
PASS_MEM_STAT); \
|
||||
} \
|
||||
\
|
||||
static inline void VEC_OP (T,A,free) \
|
||||
|
@ -721,9 +736,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
|||
\
|
||||
if (len_) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve \
|
||||
(NULL, -len_ PASS_MEM_STAT)); \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact \
|
||||
(NULL, len_ PASS_MEM_STAT)); \
|
||||
\
|
||||
new_vec_->base.num = len_; \
|
||||
memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
|
||||
|
@ -734,8 +748,7 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
|||
static inline int VEC_OP (T,A,reserve) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
|
||||
alloc_ < 0 ? -alloc_ : alloc_ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
|
@ -744,14 +757,28 @@ static inline int VEC_OP (T,A,reserve) \
|
|||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline int VEC_OP (T,A,reserve_exact) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
*vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_ \
|
||||
PASS_MEM_STAT); \
|
||||
\
|
||||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline void VEC_OP (T,A,safe_grow) \
|
||||
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
VEC_ASSERT (size_ >= 0 \
|
||||
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
|
||||
"grow", T, A); \
|
||||
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_OP (T,A,reserve_exact) (vec_, \
|
||||
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_BASE (*vec_)->num = size_; \
|
||||
} \
|
||||
\
|
||||
|
@ -972,11 +999,10 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
|
|||
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
|
||||
(int alloc_ MEM_STAT_DECL) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \
|
||||
offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) \
|
||||
PASS_MEM_STAT); \
|
||||
return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \
|
||||
offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) \
|
||||
PASS_MEM_STAT); \
|
||||
} \
|
||||
\
|
||||
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
||||
|
@ -986,9 +1012,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
|||
\
|
||||
if (len_) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \
|
||||
(NULL, -len_, \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
|
||||
(NULL, len_, \
|
||||
offsetof (VEC(T,A),base.vec), sizeof (T) \
|
||||
PASS_MEM_STAT)); \
|
||||
\
|
||||
|
@ -1009,8 +1034,7 @@ static inline void VEC_OP (T,A,free) \
|
|||
static inline int VEC_OP (T,A,reserve) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
|
||||
alloc_ < 0 ? -alloc_ : alloc_ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
|
@ -1022,14 +1046,30 @@ static inline int VEC_OP (T,A,reserve) \
|
|||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline int VEC_OP (T,A,reserve_exact) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
|
||||
(*vec_, alloc_, \
|
||||
offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) PASS_MEM_STAT); \
|
||||
\
|
||||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline void VEC_OP (T,A,safe_grow) \
|
||||
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
VEC_ASSERT (size_ >= 0 \
|
||||
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
|
||||
"grow", T, A); \
|
||||
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_OP (T,A,reserve_exact) (vec_, \
|
||||
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_BASE (*vec_)->num = size_; \
|
||||
} \
|
||||
\
|
||||
|
@ -1064,11 +1104,9 @@ static inline T *VEC_OP (T,A,safe_insert) \
|
|||
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
|
||||
(int alloc_ MEM_STAT_DECL) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \
|
||||
offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) \
|
||||
PASS_MEM_STAT); \
|
||||
return (VEC(T,A) *) vec_##A##_o_reserve_exact \
|
||||
(NULL, alloc_, offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) PASS_MEM_STAT); \
|
||||
} \
|
||||
\
|
||||
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
||||
|
@ -1078,9 +1116,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
|
|||
\
|
||||
if (len_) \
|
||||
{ \
|
||||
/* We must request exact size allocation, hence the negation. */ \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \
|
||||
(NULL, -len_, \
|
||||
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
|
||||
(NULL, len_, \
|
||||
offsetof (VEC(T,A),base.vec), sizeof (T) \
|
||||
PASS_MEM_STAT)); \
|
||||
\
|
||||
|
@ -1101,8 +1138,7 @@ static inline void VEC_OP (T,A,free) \
|
|||
static inline int VEC_OP (T,A,reserve) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
|
||||
alloc_ < 0 ? -alloc_ : alloc_ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
|
@ -1114,14 +1150,29 @@ static inline int VEC_OP (T,A,reserve) \
|
|||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline int VEC_OP (T,A,reserve_exact) \
|
||||
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
|
||||
VEC_CHECK_PASS); \
|
||||
\
|
||||
if (extend) \
|
||||
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
|
||||
(*vec_, alloc_, offsetof (VEC(T,A),base.vec), \
|
||||
sizeof (T) PASS_MEM_STAT); \
|
||||
\
|
||||
return extend; \
|
||||
} \
|
||||
\
|
||||
static inline void VEC_OP (T,A,safe_grow) \
|
||||
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
|
||||
{ \
|
||||
VEC_ASSERT (size_ >= 0 \
|
||||
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
|
||||
"grow", T, A); \
|
||||
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_OP (T,A,reserve_exact) (vec_, \
|
||||
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
|
||||
VEC_CHECK_PASS PASS_MEM_STAT); \
|
||||
VEC_BASE (*vec_)->num = size_; \
|
||||
} \
|
||||
\
|
||||
|
|
Loading…
Add table
Reference in a new issue