/** @license 2017 Neil Edelman, distributed under the terms of the [MIT License](https://opensource.org/licenses/MIT). @abstract Source ; examples . @subtitle Doubly-linked component ![Example of a stochastic skip-list.](../web/list.png) In parlance of , list> is a circular header, or sentinel, to a doubly-linked list of listlink>. This is a closed structure, such that with with a pointer to any element, it is possible to extract the entire list. @param[LIST_NAME] `` that satisfies `C` naming conventions when mangled; required. `` is private, whose names are prefixed in a manner to avoid collisions. @param[LIST_EXPECT_TRAIT] Do not un-define certain variables for subsequent inclusion in a trait. @param[LIST_COMPARE_NAME, LIST_COMPARE, LIST_IS_EQUAL] Compare trait contained in . An optional mangled name for uniqueness and a function implementing either compare_fn> or bipredicate_fn>. @param[LIST_TO_STRING_NAME, LIST_TO_STRING] To string trait contained in . An optional mangled name for uniqueness and function implementing to_string_fn>. @std C89 */ #ifndef LIST_NAME #error Name LIST_NAME undefined. #endif #if defined(LIST_TO_STRING_NAME) || defined(LIST_TO_STRING) /* */ #if defined(LIST_COMPARE_NAME) || defined(LIST_COMPARE) \ || defined(LIST_IS_EQUAL) /* */ #define LIST_TRAITS LIST_TO_STRING_TRAIT + LIST_COMPARE_TRAIT #if LIST_TRAITS > 1 #error Only one trait per include is allowed; use LIST_EXPECT_TRAIT. #endif #if LIST_TRAITS && !defined(LIST_BASE) #error Trying to define a trait without defining the base datatype. #endif #if defined(LIST_TO_STRING_NAME) && !defined(LIST_TO_STRING) #error LIST_TO_STRING_NAME requires LIST_TO_STRING. #endif #if defined(LIST_COMPARE_NAME) \ && (!(!defined(LIST_COMPARE) ^ !defined(LIST_IS_EQUAL))) #error LIST_COMPARE_NAME requires LIST_COMPARE or LIST_IS_EQUAL not both. #endif #ifndef LIST_H /* */ #if LIST_TRAITS == 0 /* */ /* */ static void PL_(unused_base_coda)(void); static void PL_(unused_base)(void) { L_(list_head)(0); L_(list_tail)(0); L_(list_previous)(0); L_(list_next)(0); L_(list_clear)(0); L_(list_add_before)(0, 0); L_(list_add_after)(0, 0); L_(list_unshift)(0, 0); L_(list_push)(0, 0); L_(list_remove)(0); L_(list_shift)(0); L_(list_pop)(0); L_(list_to)(0, 0); L_(list_to_before)(0, 0); L_(list_to_if)(0, 0, 0); L_(list_for_each)(0, 0); L_(list_any)(0, 0); L_(list_self_correct)(0); PL_(begin)(0, 0); PL_(next)(0); PL_(unused_base_coda)(); } static void PL_(unused_base_coda)(void) { PL_(unused_base)(); } #elif defined(LIST_TO_STRING) /* base code --> */ #define TO_STRING LIST_TO_STRING #include "to_string.h" /** \include */ #ifdef LIST_TEST /* */ #undef SZ_ #undef LIST_TO_STRING #ifdef LIST_TO_STRING_NAME #undef LIST_TO_STRING_NAME #endif #else /* to string trait --> */ #include "list_coda.h" /** \include */ #ifdef LIST_TEST /* */ #undef LC_ #ifdef LIST_COMPARE_NAME #undef LIST_COMPARE_NAME #endif #ifdef LIST_COMPARE #undef LIST_COMPARE #endif #ifdef LIST_IS_EQUAL #undef LIST_IS_EQUAL #endif #endif /* traits --> */ #ifdef LIST_EXPECT_TRAIT /* */ #endif /* !trait --> */ #undef LIST_TO_STRING_TRAIT #undef LIST_COMPARE_TRAIT #undef LIST_TRAITS