Marc Nieper-Wißkirchen wrote:
> For example, given a list of fruits, insert "pear" after each "apple" and
> "peach" before each "apple". This can be easily done through
> gl_list_add_before/gl_list_add_after/gl_list_next_node without using
> invalidated nodes.
Now I see what you mean. Quasi companion functions to gl_list_next_node
and gl_list_previous_node: gl_list_first_node and gl_list_last_node,
respectively.
I'm sorry for any confusion. I should have expressed myself more clearly in my initial email.
> What I want to propose is to allow the NULL value in
> gl_next_node/gl_previous_node. In this case, gl_next_node shall return the
> first node and gl_previous_node shall return the last node.
Yes, gl_list_first_node and gl_list_last_node are indeed much better. I was only worried about the size of the vtable.
I don't think this encourages robust programs. If a program passes a NULL
pointer to gl_list_next_node or gl_list_previous_node, the program should
better crash.
> PS What can't be done (because gl_list_remove doesn't return a valid
> (next?) node) is list walking algorithms that both remove and insert nodes.
> For removal, one has to use an iterator.
Yes, some algorithms need a second, temporary list. Not all algorithms
can be written to use the original list, be efficient in O() terms, and
be implementation-independent.
Speaking of this, this is not always non-trivial if the dispose function is not NULL. Consider an algorithm that processes one list to produce a new one. In the end, the old list shall be removed but the items that have ended up in the new list shall not be disposed. I guess that the canonical way to achieve this is to use gl_list_set to overwrite the values in the old list with dummy values (e.g. NULL) so that they are not freed on eventual removal.
-- Marc