ListRemoveRange
Description
Remove count elements starting at start and optionally copy them out.
Parameters
| Name | Direction | Description |
|---|---|---|
l |
in,out | List handle. |
rd |
out | Optional destination buffer of at least count slots. Pass NULL to discard the removed elements (the configured copy_deinit is invoked instead). |
start |
in | First removed index. |
count |
in | Number of elements to remove. |
Success
Returns to the caller. count nodes starting at start are unlinked and their storage freed; list length shrinks by count. When rd is non-NULL the removed values are memcopied into *rd in order. When rd is NULL and copy_deinit is configured, the handler is invoked on each removed element.
Failure
Function cannot fail. start + count exceeding length is a caller bug and aborts via LOG_FATAL.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
ListInt.c:152:
if (ListLen(list) > 0 && start < ListLen(list) && count > 0 && start + count <= ListLen(list)) {
i32 removed_items[16];
ListRemoveRange(list, removed_items, start, count);
}
break;- In
List.Remove.c:78:
static bool test_list_remove_range_and_delete_aliases(void) {
WriteFmt("Testing ListRemoveRange and delete aliases\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Remove.c:93:
ListPushBackR(&list, 6);
ListRemoveRange(&list, removed, 2, 2);
bool result = (removed[0] == 3) && (removed[1] == 4);
result = result && list_matches(GENERIC_LIST(&list), (const int[]) {1, 2, 5, 6}, 4);
static bool test_list_remove_range_prefix_suffix_edges(void) {
WriteFmt("Testing ListRemoveRange prefix/suffix edges\n");
DefaultAllocator alloc = DefaultAllocatorInit(); ListPushBackR(&list, 6);
ListRemoveRange(&list, prefix, 0, 2);
bool result = (prefix[0] == 1) && (prefix[1] == 2);
result = result && list_matches(GENERIC_LIST(&list), (const int[]) {3, 4, 5, 6}, 4); result = result && list_matches(GENERIC_LIST(&list), (const int[]) {3, 4, 5, 6}, 4);
ListRemoveRange(&list, suffix, 2, 2);
result = result && (suffix[0] == 5) && (suffix[1] == 6);
result = result && list_matches(GENERIC_LIST(&list), (const int[]) {3, 4}, 2);
static bool test_list_remove_range_whole_list_to_buffer(void) {
WriteFmt("Testing ListRemoveRange whole-list buffered removal\n");
DefaultAllocator alloc = DefaultAllocatorInit(); ListPushBackR(&list, 8);
ListPushBackR(&list, 9);
ListRemoveRange(&list, removed, 0, 3);
bool result = (removed[0] == 7) && (removed[1] == 8) && (removed[2] == 9);
static bool test_list_remove_zero_count_and_deep_copy_delete(void) {
WriteFmt("Testing ListRemoveRange zero-count and deep-copy delete\n");
DefaultAllocator alloc = DefaultAllocatorInit(); ListPushBackR(&list, 9);
ListRemoveRange(&list, NULL, 1, 0);
ListRemoveRange(&list, NULL, ListLen(&list), 0);
ListRemoveRange(&list, NULL, 9999, 0);
ListRemoveRange(&list, NULL, 1, 0);
ListRemoveRange(&list, NULL, ListLen(&list), 0);
ListRemoveRange(&list, NULL, 9999, 0);
bool result = (g_copy_init_count == 3); ListRemoveRange(&list, NULL, 1, 0);
ListRemoveRange(&list, NULL, ListLen(&list), 0);
ListRemoveRange(&list, NULL, 9999, 0);
bool result = (g_copy_init_count == 3);
result = result && (g_copy_deinit_count == 0);
static bool test_list_remove_range_with_deep_copy_buffer(void) {
WriteFmt("Testing ListRemoveRange buffer semantics with deep copy\n");
DefaultAllocator alloc = DefaultAllocatorInit(); ListPushBackR(&list, 6);
ListRemoveRange(&list, removed, 1, 2);
bool result = (g_copy_init_count == 3);
static bool test_list_remove_range_out_of_range_fails(void) {
WriteFmt("Testing ListRemoveRange out of range\n");
List(int) list = ListInit(get_test_alloc()); ListPushBackR(&list, 10);
ListPushBackR(&list, 20);
ListRemoveRange(&list, NULL, 1, 2);
return false;- In
Remove.h:137:
/// TAGS: List, Delete, Range
///
#define ListDeleteRange(l, start, count) ListRemoveRange((l), NULL, (start), (count))
#endif // MISRA_STD_CONTAINER_LIST_REMOVE_H
Last updated on