LeoVen/C-Macro-Collections

list.h - a couple of issues

Closed this issue · 4 comments

Line 299, I think it should be
memmove(list->buffer, list->buffer + 1, (list->count - 1) * sizeof(V));

Line 311, I think it should be
memmove(list->buffer + index, list->buffer + index + 1, (list->count - index - 1) * sizeof(V));

I also suggest calling PFX##_pop_at(list, 0) inside PFX##_pop_front.
Also, all of the pop functions should be calling deallocators

How about this:

bool PFX##_pop_range(struct SNAME *list, size_t beg, size_t end)
{
if (PFX##_empty(list) || beg > end || end > list->count)
return false;

if (list->deallocator)
{
size_t i = beg;
for (; i < end ; i++)
list->deallocator(list->buffer[i]);
}

size_t length = end - beg;
size_t remain = list->count - end;
if (remain > 0)
memmove(&list->buffer[beg], &list->buffer[end], remain * sizeof(V));
list->count -= length;
memset(&list->buffer[list->count], 0, length * sizeof(V));

return true;
}

bool PFX##_pop_at(struct SNAME *list, size_t i)
{
return PFX##_pop_range(list, i, i + 1);
}

bool PFX##_pop_front(struct SNAME *list)
{
return PFX##_pop_at(list, 0);
}

bool PFX##_pop_back(struct SNAME *list)
{
return PFX##_pop_at(list, list->count - 1);
}

void PFX##_pop_if(struct SNAME *list, bool (condition)(V))
{
int
indices = malloc(list->count * sizeof(int));
int i;
for (i = list->count - 1; i >= 0 ; --i)
indices[i] = condition(list->buffer[i]) ? i : -1;

for (i = list->count - 1; i >= 0 ; --i)
{
if (indices[i] != -1)
PFX##_pop_at(list, indices[i]);
}
free(indices);
} \

In the last post I’ve realised that I don’t need to preallocate indices. I don’t know what I was thinking

Hi thank you for the suggestion. The indices are indeed wrong. I will get them fixed in the next release.

Regarding calling PFX##_pop_at(list, 0) inside PFX##_pop_front won't happen because I have another utility to this library cooking up. You will be able to set callback functions for each of the main functions of each collection. This means that if you set a callback function to PFX##_pop_at it will activate when PFX##_pop_front is called too. This, of course, could change.

Regarding deallocating the elements when it is popped: this was a design decision. What if the element being popped in a list is also handled by another list? O maybe another collection? So to get it freed from memory you will have to first access it with PFX##_get and then deallocate it.

This has been already fixed in the dev branch by b2bef4e