vector: Add null-termination
This commit is contained in:
@@ -39,6 +39,12 @@ G_BEGIN_DECLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
#define GTK_VECTOR_REAL_SIZE(_size) ((_size) + 1)
|
||||
#else
|
||||
#define GTK_VECTOR_REAL_SIZE(_size) (_size)
|
||||
#endif
|
||||
|
||||
/* make this readable */
|
||||
#define _T_ GTK_VECTOR_ELEMENT_TYPE
|
||||
#define GtkVector GTK_VECTOR_TYPE_NAME
|
||||
@@ -54,7 +60,7 @@ struct GtkVector
|
||||
_T_ *end;
|
||||
_T_ *end_allocation;
|
||||
#ifdef GTK_VECTOR_PREALLOC
|
||||
_T_ preallocated[GTK_VECTOR_PREALLOC];
|
||||
_T_ preallocated[GTK_VECTOR_REAL_SIZE(GTK_VECTOR_PREALLOC)];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -66,6 +72,9 @@ gtk_vector(init) (GtkVector *self)
|
||||
self->start = self->preallocated;
|
||||
self->end = self->start;
|
||||
self->end_allocation = self->start + GTK_VECTOR_PREALLOC;
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
*self->start = *(_T_[1]) {};
|
||||
#endif
|
||||
#else
|
||||
self->start = NULL;
|
||||
self->end = NULL;
|
||||
@@ -130,7 +139,7 @@ gtk_vector(is_empty) (GtkVector *self)
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gtk_vector(reserve) (GtkVector *self,
|
||||
gsize n)
|
||||
gsize n)
|
||||
{
|
||||
gsize new_size, size;
|
||||
|
||||
@@ -138,13 +147,21 @@ gtk_vector(reserve) (GtkVector *self,
|
||||
return;
|
||||
|
||||
size = gtk_vector(get_size) (self);
|
||||
new_size = 1 << g_bit_storage (MAX (n, 16) - 1);
|
||||
new_size = 1 << g_bit_storage (MAX (GTK_VECTOR_REAL_SIZE (n), 16) - 1);
|
||||
|
||||
#ifdef GTK_VECTOR_PREALLOC
|
||||
if (self->start == self->preallocated)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
memcpy (self->start, self->preallocated, sizeof (_T_) * size);
|
||||
memcpy (self->start, self->preallocated, sizeof (_T_) * GTK_VECTOR_REAL_SIZE (size));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
if (self->start == NULL)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
*self->start = *(_T_[1]) {};
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -152,6 +169,9 @@ gtk_vector(reserve) (GtkVector *self,
|
||||
|
||||
self->end = self->start + size;
|
||||
self->end_allocation = self->start + new_size;
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
self->end_allocation--;
|
||||
#endif
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
@@ -161,19 +181,22 @@ gtk_vector(splice) (GtkVector *self,
|
||||
_T_ *additions,
|
||||
gsize added)
|
||||
{
|
||||
gssize size = gtk_vector(get_size) (self);
|
||||
gsize size;
|
||||
gsize remaining;
|
||||
|
||||
size = gtk_vector(get_size) (self);
|
||||
g_assert (pos + removed <= size);
|
||||
remaining = size - pos - removed;
|
||||
|
||||
gtk_vector(free_elements) (gtk_vector(index) (self, pos),
|
||||
gtk_vector(index) (self, pos + removed));
|
||||
|
||||
gtk_vector(reserve) (self, size - removed + added);
|
||||
|
||||
if (pos + removed < size && removed != added)
|
||||
if (GTK_VECTOR_REAL_SIZE (remaining) && removed != added)
|
||||
memmove (gtk_vector(index) (self, pos + added),
|
||||
gtk_vector(index) (self, pos + removed),
|
||||
(size - pos - removed) * sizeof (_T_));
|
||||
GTK_VECTOR_REAL_SIZE (remaining) * sizeof (_T_));
|
||||
|
||||
if (added)
|
||||
memcpy (gtk_vector(index) (self, pos),
|
||||
@@ -210,10 +233,12 @@ gtk_vector(get) (GtkVector *self,
|
||||
#undef gtk_vector_paste_more
|
||||
#undef gtk_vector_paste
|
||||
#undef gtk_vector
|
||||
#undef GTK_VECTOR_REAL_SIZE
|
||||
|
||||
#undef GTK_VECTOR_PREALLOC
|
||||
#undef GTK_VECTOR_ELEMENT_TYPE
|
||||
#undef GTK_VECTOR_NAME
|
||||
#undef GTK_VECTOR_TYPE_NAME
|
||||
#undef GTK_VECTOR_PREALLOC
|
||||
#undef GTK_VECTOR_NULL_TERMINATED
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,34 @@ int_free_func (int data)
|
||||
#define GTK_VECTOR_FREE_FUNC int_free_func
|
||||
#include "vectorimpl.c"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE int
|
||||
#define GTK_VECTOR_NAME null_int_vector
|
||||
#define GTK_VECTOR_TYPE_NAME NullIntVector
|
||||
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||
#include "vectorimpl.c"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE int
|
||||
#define GTK_VECTOR_NAME null_pre_int_vector
|
||||
#define GTK_VECTOR_TYPE_NAME NullPreIntVector
|
||||
#define GTK_VECTOR_PREALLOC 100
|
||||
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||
#include "vectorimpl.c"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE int
|
||||
#define GTK_VECTOR_NAME null_free_int_vector
|
||||
#define GTK_VECTOR_TYPE_NAME NullFreeIntVector
|
||||
#define GTK_VECTOR_FREE_FUNC int_free_func
|
||||
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||
#include "vectorimpl.c"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE int
|
||||
#define GTK_VECTOR_NAME null_pre_free_int_vector
|
||||
#define GTK_VECTOR_TYPE_NAME NullPreFreeIntVector
|
||||
#define GTK_VECTOR_PREALLOC 100
|
||||
#define GTK_VECTOR_FREE_FUNC int_free_func
|
||||
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||
#include "vectorimpl.c"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -59,11 +87,19 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/intvector/simple", int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/prealloc/simple", pre_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/freefunc/simple", free_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/prealloc_freefunc_simple", pre_free_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/prealloc/freefunc/simple", pre_free_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/null/simple", null_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/null/prealloc/simple", null_pre_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/null/freefunc/simple", null_free_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/null/prealloc/freefunc/simple", null_pre_free_int_vector_test_simple);
|
||||
g_test_add_func ("/intvector/splice", int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/prealloc/splice", pre_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/freefunc/splice", free_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/prealloc_freefunc_splice", pre_free_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/prealloc/freefunc/splice", pre_free_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/null/splice", null_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/null/prealloc/splice", null_pre_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/null/freefunc/splice", null_free_int_vector_test_splice);
|
||||
g_test_add_func ("/intvector/null/prealloc/freefunc/splice", null_pre_free_int_vector_test_splice);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ gtk_vector(test_simple) (void)
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), ==, i);
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), <=, gtk_vector(get_capacity) (&v));
|
||||
gtk_vector(append) (&v, i);
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
g_assert_cmpint (*gtk_vector(index) (&v, gtk_vector(get_size) (&v)), ==, 0);
|
||||
#endif
|
||||
}
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), ==, i);
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), <=, gtk_vector(get_capacity) (&v));
|
||||
@@ -84,6 +87,10 @@ gtk_vector(test_splice) (void)
|
||||
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), ==, old_size + add - remove);
|
||||
g_assert_cmpint (gtk_vector(get_size) (&v), <=, gtk_vector(get_capacity) (&v));
|
||||
#ifdef GTK_VECTOR_NULL_TERMINATED
|
||||
if (gtk_vector(get_size) (&v))
|
||||
g_assert_cmpint (*gtk_vector(index) (&v, gtk_vector(get_size) (&v)), ==, 0);
|
||||
#endif
|
||||
for (j = 0; j < add; j++)
|
||||
g_assert_cmpint (gtk_vector(get) (&v, pos + j), ==, additions[j]);
|
||||
}
|
||||
@@ -100,9 +107,11 @@ gtk_vector(test_splice) (void)
|
||||
#undef gtk_vector_paste_more
|
||||
#undef gtk_vector_paste
|
||||
#undef gtk_vector
|
||||
#undef GTK_VECTOR_REAL_SIZE
|
||||
|
||||
#undef GTK_VECTOR_PREALLOC
|
||||
#undef GTK_VECTOR_ELEMENT_TYPE
|
||||
#undef GTK_VECTOR_NAME
|
||||
#undef GTK_VECTOR_TYPE_NAME
|
||||
#undef GTK_VECTOR_PREALLOC
|
||||
#undef GTK_VECTOR_NULL_TERMINATED
|
||||
|
||||
|
||||
Reference in New Issue
Block a user