List
Description
Double linked list.
Fields
| Name | Description |
|---|---|
head |
Reference to head node of linked list. |
tail |
Reference to tail node of linked list. |
copy_init |
A user-provided type-specific method to initialize copies of types. |
copy_deinit |
A user-provided type-specific method deinitialize already created copies of types. |
length |
Length of this linked list. |
Usage example (Cross-references)
Usage examples (Cross-references)
- In
List.c:8:
/// merge primitives consumed by the typed `List(T)` macros.
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>
#include <Misra/Std/Memory.h>- In
List.c:112:
}
if (start + count > list->length) {
LOG_FATAL("List range out of bounds.");
}- In
List.c:402:
static void validate_list_structural(const GenericList *l) {
if (!l->allocator) {
LOG_FATAL("List allocator pointer is NULL.");
}
if (!l->allocator->allocate || !l->allocator->resize || !l->allocator->remap || !l->allocator->deallocate) {- In
List.c:419:
}
if (l->head->prev) {
LOG_FATAL("List head must not have a previous node.");
}
if (l->tail->next) {- In
List.c:422:
}
if (l->tail->next) {
LOG_FATAL("List tail must not have a next node.");
}
}- In
List.c:429:
void validate_list(const GenericList *l) {
if (!l) {
LOG_FATAL("List pointer is NULL.");
}
if (!MAGIC_MATCHES(l->__magic, LIST_MAGIC)) {- In
ListInt.c:9:
#include "../Harness.h"
#include "ListInt.h"
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>- In
ListInt.h:10:
#define FUZZ_LIST_INT_H
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Types.h>- In
ListInt.h:15:
// List(i32) typedef
typedef List(i32) IntList;
// List(i32) function enumeration
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) LI;
LI li = ListInit(ALLOCATOR_OF(&alloc));
ListForeach(&li, i) {- In
List.Init.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>- In
List.Init.c:29:
static bool test_list_init_variants(void) {
WriteFmt("Testing List init variants\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Init.c:33:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list_a = ListInit(&alloc);
IntList list_b = ListInitT(list_b, &alloc);- In
List.Init.c:58:
static bool test_list_init_optional_allocator(void) {
WriteFmt("Testing List init optional allocator\n");
typedef List(int) IntList;- In
List.Init.c:60:
WriteFmt("Testing List init optional allocator\n");
typedef List(int) IntList;
DefaultAllocator alloc = DefaultAllocatorInit();
// intentional bypass: no public setter on `Allocator` for effort /
- In
List.Init.c:94:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);- In
List.Init.c:122:
};
WriteFmt("[INFO] Starting List.Init tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Init");
}- In
List.Init.c:123:
WriteFmt("[INFO] Starting List.Init tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Init");
}- In
List.Insert.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>
#include <Misra/Types.h>- In
List.Insert.c:45:
static bool test_list_insert_and_push_aliases(void) {
WriteFmt("Testing List insert and push aliases\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Insert.c:49:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int a = 10;- In
List.Insert.c:85:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int arr[] = {1, 2, 3}; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int arr[] = {4, 5, 6};
static bool test_list_insert_with_deep_copy(void) {
WriteFmt("Testing List insert with deep copy\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);
int x = 7; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList dest = ListInit(&alloc);
IntList src = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);
static bool test_list_merge_variants(void) {
WriteFmt("Testing List merge variants\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList dest_l = ListInit(&alloc);
IntList src_l = ListInit(&alloc);
static bool test_list_merge_edge_cases(void) {
WriteFmt("Testing List merge edge cases\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList deep_dest = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);
IntList shallow_src = ListInit(&alloc); };
WriteFmt("[INFO] Starting List.Insert tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Insert");
}
WriteFmt("[INFO] Starting List.Insert tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Insert");
}- In
List.Foreach.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>
static bool test_list_foreach_basic(void) {
WriteFmt("Testing basic List foreach macros\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int reverse_values[5] = {0};
static bool test_list_foreach_ranges(void) {
WriteFmt("Testing ranged List foreach macros\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int forward_range_sum = 0;
static bool test_list_foreach_range_edge_cases(void) {
WriteFmt("Testing List ranged foreach edge cases\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int count = 0;
static bool test_list_foreach_index_variants(void) {
WriteFmt("Testing indexed List foreach macros\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int reverse_values[5] = {0};
static bool test_list_foreach_index_jump_contract(void) {
WriteFmt("Testing indexed List foreach jump contract\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int forward_values[3] = {0};
static bool test_list_foreach_empty_lists(void) {
WriteFmt("Testing List foreach macros on empty list\n");
DefaultAllocator alloc = DefaultAllocatorInit(); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
u64 count = 0; };
WriteFmt("[INFO] Starting List.Foreach tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Foreach");
}
WriteFmt("[INFO] Starting List.Foreach tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Foreach");
}- In
List.Ops.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>- In
List.Ops.c:54:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);- In
List.Ops.c:78:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);- In
List.Ops.c:103:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList empty = ListInit(&alloc);
IntList singleton = ListInit(&alloc);- In
List.Ops.c:127:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);- In
List.Ops.c:158:
};
WriteFmt("[INFO] Starting List.Ops tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Ops");
}- In
List.Ops.c:159:
WriteFmt("[INFO] Starting List.Ops tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Ops");
}- In
List.Access.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>
#include <Misra/Types.h>- In
List.Access.c:34:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);- In
List.Access.c:60:
static bool test_list_value_access_and_swap(void) {
WriteFmt("Testing List accessors and swap\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Access.c:64:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);- In
List.Access.c:90:
static bool test_list_node_access_and_navigation(void) {
WriteFmt("Testing List node access and navigation\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Access.c:94:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc); DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc); };
WriteFmt("[INFO] Starting List.Access tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Access");
}
WriteFmt("[INFO] Starting List.Access tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Access");
}- In
List.Remove.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>
#include <Misra/Types.h>- In
List.Remove.c:49:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int removed = 0;- In
List.Remove.c:82:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int removed[2] = {0, 0}; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int prefix[2] = {0, 0}; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);
int removed[3] = {0, 0, 0}; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);
int removed = 0; DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInitWithDeepCopy(tracked_copy_init, tracked_copy_deinit, &alloc);
int removed[2] = {0, 0}; };
WriteFmt("[INFO] Starting List.Remove tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Remove");
}
WriteFmt("[INFO] Starting List.Remove tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Remove");
}- In
List.Deadend.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h> WriteFmt("Testing ValidateList on corrupt empty list\n");
List(int) list = ListInit(get_test_alloc());
// intentional bypass: ListHead is read-only, no public setter exists --
// plant a bogus head pointer on an empty list so ValidateList trips its
WriteFmt("Testing ValidateList on invalid magic\n");
List(int) list = ListInit(get_test_alloc());
// intentional bypass: __magic is the private sentinel ValidateList
// checks; scramble it directly to exercise the type-confusion /
GenericListNode node = {0};
List(int) list = ListInit(get_test_alloc());
GenericList *g = GENERIC_LIST(&list); int value = 1;
GenericListNode node = {.next = NULL, .prev = NULL, .data = &value};
List(int) list = ListInit(get_test_alloc());
GenericList *g = GENERIC_LIST(&list); int value = 1;
GenericListNode node = {.next = NULL, .prev = (GenericListNode *)1, .data = &value};
List(int) list = ListInit(get_test_alloc());
GenericList *g = GENERIC_LIST(&list); int value = 1;
GenericListNode node = {.next = (GenericListNode *)1, .prev = NULL, .data = &value};
List(int) list = ListInit(get_test_alloc());
GenericList *g = GENERIC_LIST(&list); WriteFmt("Testing ListPtrAt on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListPtrAt(&list, 0); WriteFmt("Testing ListPtrAt out of bounds\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListPtrAt(&list, 1); WriteFmt("Testing ListAt out of bounds\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
(void)ListAt(&list, 1); WriteFmt("Testing ListNodePtrAt on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListNodePtrAt(&list, 0); WriteFmt("Testing ListNodePtrAt out of bounds\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListNodePtrAt(&list, 1); WriteFmt("Testing ListNodeAt out of bounds\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
(void)ListNodeAt(&list, 1); WriteFmt("Testing ListFirst on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListFirst(&list); WriteFmt("Testing ListLast on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListLast(&list); WriteFmt("Testing ListNodeAt on empty list\n");
List(int) list = ListInit(get_test_alloc());
(void)ListNodeAt(&list, 0); WriteFmt("Testing ListInsertR out of range\n");
List(int) list = ListInit(get_test_alloc());
ListInsertR(&list, 10, 1); WriteFmt("Testing ListRemove out of range\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListRemove(&list, NULL, 1); WriteFmt("Testing ListPopFront on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListPopFront(&list, NULL); WriteFmt("Testing ListPopBack on empty list\n");
List(int) list = ListInit(get_test_alloc());
ListPopBack(&list, NULL); WriteFmt("Testing ListRemoveRange out of range\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListPushBackR(&list, 20); WriteFmt("Testing ListSwapItems out of range\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListSwapItems(&list, 0, 1); WriteFmt("Testing ListFind without compare function\n");
List(int) list = ListInit(get_test_alloc());
int key = 10;
ListPushBackR(&list, 10); WriteFmt("Testing ListFind without key pointer\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListFind(&list, NULL, compare_ints); WriteFmt("Testing ListSort without compare function\n");
List(int) list = ListInit(get_test_alloc());
ListPushBackR(&list, 10);
ListSort(&list, NULL); };
WriteFmt("[INFO] Starting List.Deadend tests\n\n");
return run_test_suite(
NULL, deadend_tests,
(int)(sizeof(deadend_tests) / sizeof(deadend_tests[0])),
"List.Deadend"
);
}- In
List.Type.c:2:
#include <Misra/Std/Allocator/Default.h>
#include <Misra/Std/Container/List.h>
#include <Misra/Std/Log.h>- In
List.Type.c:8:
static bool test_list_type_defaults(void) {
WriteFmt("Testing List type defaults\n");
DefaultAllocator alloc = DefaultAllocatorInit();- In
List.Type.c:12:
DefaultAllocator alloc = DefaultAllocatorInit();
typedef List(int) IntList;
IntList list = ListInit(&alloc);- In
List.Type.c:47:
};
WriteFmt("[INFO] Starting List.Type tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Type");
}- In
List.Type.c:48:
WriteFmt("[INFO] Starting List.Type tests\n\n");
return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "List.Type");
}- In
Container.h:22:
#endif
#if FEATURE_LIST
# include <Misra/Std/Container/List.h>
#endif
#if FEATURE_MAP- In
List.h:11:
// clang-format off
#include "List/Type.h"
#include "List/Init.h"
#include "List/Insert.h"- In
List.h:12:
// clang-format off
#include "List/Type.h"
#include "List/Init.h"
#include "List/Insert.h"
#include "List/Remove.h"- In
List.h:13:
#include "List/Type.h"
#include "List/Init.h"
#include "List/Insert.h"
#include "List/Remove.h"
#include "List/Access.h"- In
List.h:14:
#include "List/Init.h"
#include "List/Insert.h"
#include "List/Remove.h"
#include "List/Access.h"
#include "List/Foreach.h"- In
List.h:15:
#include "List/Insert.h"
#include "List/Remove.h"
#include "List/Access.h"
#include "List/Foreach.h"
#include "List/Ops.h"- In
List.h:16:
#include "List/Remove.h"
#include "List/Access.h"
#include "List/Foreach.h"
#include "List/Ops.h"
#include "List/Private.h"- In
List.h:17:
#include "List/Access.h"
#include "List/Foreach.h"
#include "List/Ops.h"
#include "List/Private.h"
// clang-format on
- In
List.h:18:
#include "List/Foreach.h"
#include "List/Ops.h"
#include "List/Private.h"
// clang-format on
Last updated on