moved remove and at functions to headers, improved remove_range functions, added string_strip + string_count, updated tests
Minclude/cutils/byte_array.h
@@ -19,14 +19,32 @@ typedef struct Bytearray
Bytearray* bytearray_with_capacity(size_t capacity, size_t element_size);
void delete_bytearray(Bytearray* bytearray, void(*rmv_el) (void*));
void* bytearray_at(const Bytearray* bytearray, size_t index);
HEDLEY_INLINE
static void* bytearray_at(const Bytearray* bytearray, size_t index)
{
return bytearray->items+(index*bytearray->element_size);
}
#define bytearray_pop(bytearray, retptr) bytearray_pop_at(bytearray, bytearray->length-1, retptr)
void* bytearray_pop_at(Bytearray* bytearray, size_t index, void* retptr);
#define bytearray_push(bytearray, item) bytearray_insert(bytearray, bytearray->length, item)
bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item);
void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*));
HEDLEY_INLINE
static void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*))
{
if(index < bytearray->length)
{
size_t length = bytearray->length;
size_t elsize = bytearray->element_size;
if(rmv)
rmv(&bytearray->items[index*elsize]);
memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, length*elsize-index*elsize-1*elsize);
bytearray->length--;
}
}
void bytearray_remove_range(Bytearray* bytearray, size_t index, size_t length, void (*rmv)(void*));
bool bytearray_adjust_size(Bytearray* bytearray, size_t size);
bool bytearray_shrink(Bytearray* bytearray);
Minclude/cutils/dyn_string.h
@@ -18,21 +18,36 @@ typedef struct String
String* string_with_capacity(size_t capacity);
void delete_string(String* string);
char string_at(const String* string, size_t index);
HEDLEY_INLINE
static char string_at(const String* string, size_t index)
{
return string->chars[index];
}
#define string_pop(string) string_pop_at(string, string->length-1)
char string_pop_at(String* string, size_t index);
bool string_insert(String* string, size_t index, char character);
#define string_push(string, character) string_insert(string, string->length, character)
void string_remove(String* string, size_t index);
HEDLEY_INLINE
static void string_remove(String* string, size_t index)
{
if(index < string->length)
{
memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars));
string->length--;
}
}
void string_remove_range(String* string, size_t index, size_t length);
size_t string_strip(String* string, char character);
bool string_adjust_size(String* string, size_t size);
/* TODO: rework find functions to take extra argument of result count
* and then find that many and return them in a vector/linked list */
bool string_find_char(const String* haystack, const char needle, size_t* pos);
bool string_find_str(const String* haystack, const String* needle, size_t* pos);
size_t string_count(const String* string, char character);
bool string_concat(String* string, const String* other);
Minclude/cutils/vector.h
@@ -18,14 +18,28 @@ typedef struct Vector
Vector* vector_with_capacity(size_t capacity);
void delete_vector(Vector* vector, void(*rmv) (void*));
void* vector_at(const Vector* vector, size_t index);
HEDLEY_INLINE
static void* vector_at(const Vector* vector, size_t index)
{
return vector->items[index];
}
#define vector_pop(vector) vector_pop_at(vector, vector->length-1)
void* vector_pop_at(Vector* vector, size_t index);
bool vector_insert(Vector* vector, size_t index, void* item);
#define vector_push(vector, item) vector_insert(vector, vector->length, item)
void vector_remove(Vector* vector, size_t index, void (*rmv)(void*));
HEDLEY_INLINE
static void vector_remove(Vector* vector, size_t index, void (*rmv)(void*))
{
if(index < vector->length)
{
if(rmv)
rmv(vector->items[index]);
memmove(vector->items+index, vector->items+index+1, (vector->length-index-1)*sizeof(*vector->items));
vector->length--;
}
}
void vector_remove_range(Vector* vector, size_t index, size_t length, void (*rmv)(void*));
bool vector_adjust_size(Vector* vector, size_t size);
Msrc/byte_array.c
@@ -38,14 +38,21 @@ void delete_bytearray(Bytearray* bytearray, void(*rmv_el) (void*))
free(bytearray);
}
void* bytearray_at(const Bytearray* bytearray, size_t index)
void bytearray_remove_range(Bytearray* bytearray, size_t index, size_t length, void (*rmv)(void*))
{
if(index >= bytearray->length)
return NULL;
else
return bytearray->items+(index*bytearray->element_size);
size_t i;
if(rmv)
{
for(i = index; i < length; i++)
{
rmv(bytearray_at(bytearray, i));
}
}
memmove(bytearray->items+index, bytearray->items+index+length, (bytearray->length-(index+length))*sizeof(*bytearray->items));
bytearray->length -= length;
}
void* bytearray_pop_at(Bytearray* bytearray, size_t index, void* retptr)
{
void *tmp;
@@ -77,20 +84,6 @@ bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item)
return true;
}
void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*))
{
if(index < bytearray->length)
{
size_t length = bytearray->length;
size_t elsize = bytearray->element_size;
if(rmv)
rmv(&bytearray->items[index*elsize]);
memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, length*elsize-index*elsize-1*elsize);
bytearray->length--;
}
}
bool bytearray_adjust_size(Bytearray* bytearray, size_t size)
{
while(bytearray->capacity < size)
Msrc/dyn_string.c
@@ -17,22 +17,37 @@ String* string_with_capacity(size_t capacity)
return string;
}
void string_remove(String* string, size_t index)
void string_remove_range(String* string, size_t index, size_t length)
{
if(index < string->length)
{
memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars));
string->length--;
}
memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)));
string->length -= length;
}
/* TODO: optimize */
void string_remove_range(String* string, size_t index, size_t length)
size_t string_strip(String* string, char character)
{
size_t i;
for(i = 0; i < length; i++)
size_t i, last = 0, offset = 0;
bool first = true;
for(i = 0; i < string->length; i++)
{
string_remove(string, index+i);
if(string_at(string,i) == character)
{
if(first)
{
first = false;
} else {
memmove(string->chars+last-offset, string->chars+last+1, i-last-1);
offset++;
}
last = i;
}
}
memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1);
string->length -= offset+(first ? 0 : 1);
return offset;
}
bool string_insert(String* string, size_t index, char character)
@@ -46,14 +61,6 @@ bool string_insert(String* string, size_t index, char character)
return true;
}
char string_at(const String* string, size_t index)
{
if(index >= string->length)
return '\0';
else
return string->chars[index];
}
char string_pop_at(String* string, size_t index)
{
char tmp = string_at(string, index);
@@ -110,6 +117,17 @@ bool string_find_str(const String* haystack, const String* needle, size_t* pos)
return false;
}
size_t string_count(const String* string, char character)
{
size_t i, ret = 0;
for(i = 0; i < string->length; i++)
{
if(string_at(string, i) == character)
ret++;
}
return ret;
}
bool string_adjust_size(String* string, size_t size)
{
while(string->capacity < size)
Msrc/test.c
@@ -112,6 +112,19 @@ static void test_string(void)
delete_string(string2);
delete_string(string);
string = from_cstring("abcd");
assert(string->length == 4);
string_remove_range(string, 0, string->length);
assert(string->length == 0);
delete_string(string);
string = from_cstring("bba");
string_strip(string, 'a');
assert(string->length == 2);
cstring = to_cstring_del(string);
free(cstring);
}
static void test_bytearray(void)
@@ -148,14 +161,18 @@ static void test_bytearray(void)
assert(*tmpchar == 'a');
free(tmpchar);
tmpchar = bytearray_pop(bt, NULL);
assert(tmpchar == NULL);
bytearray_push(bt, "a");
tmpchar = bytearray_pop(bt, NULL);
assert(*tmpchar == 'a');
free(tmpchar);
bytearray_push(bt, "a");
bytearray_push(bt, "a");
bytearray_push(bt, "a");
assert(bt->length == 3);
bytearray_remove_range(bt, 0, bt->length, NULL);
assert(bt->length == 0);
delete_bytearray(bt, NULL);
}
#if __STDC_VERSION__ >= 201112L
@@ -242,6 +259,7 @@ static void test_ll(void)
ll_remove_range(ll, 0, ll->length-1, NULL);
assert(ll->length == 1);
delete_ll(ll, NULL);
}
Msrc/vector.c
@@ -17,14 +17,6 @@ Vector* vector_with_capacity(size_t capacity)
return vector;
}
void* vector_at(const Vector* vector, size_t index)
{
if(index >= vector->length)
return NULL;
else
return vector->items[index];
}
void* vector_pop_at(Vector* vector, size_t index)
{
void* tmp = vector_at(vector, index);
@@ -37,25 +29,18 @@ void* vector_pop_at(Vector* vector, size_t index)
}
}
void vector_remove(Vector* vector, size_t index, void (*rmv)(void*))
{
if(index < vector->length)
{
if(rmv)
rmv(vector->items[index]);
memmove(vector->items+index, vector->items+index+1, (vector->length-index-1)*sizeof(*vector->items));
vector->length--;
}
}
/* TODO: optimize */
void vector_remove_range(Vector* vector, size_t index, size_t length, void (*rmv)(void*))
{
size_t i;
for(i = 0; i < length; i++)
if(rmv)
{
vector_remove(vector, index+i, rmv);
for(i = index; i < length; i++)
{
rmv(vector_at(vector, i));
}
}
memmove(vector->items+index, vector->items+index+length, (vector->length-(index+length))*sizeof(*vector->items));
vector->length -= length;
}
size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*))