10static void * __cstl_slist_element(
const struct cstl_slist *
const s,
13 return (
void *)((uintptr_t)n - s->off);
18 const struct cstl_slist *
const s,
const void *
const e)
24static void __cstl_slist_insert_after(
struct cstl_slist *
const sl,
28 assert(sl->t->n == NULL);
37 assert(sl->t->n == NULL);
46 assert(sl->t->n == NULL);
51 assert(sl->t->n == NULL);
59 void *
const e,
void *
const n)
61 __cstl_slist_insert_after(
62 sl, __cstl_slist_node(sl, e), __cstl_slist_node(sl, n));
67 return __cstl_slist_element(
68 sl, __cstl_slist_erase_after(sl, __cstl_slist_node(sl, e)));
73 __cstl_slist_insert_after(sl, &sl->h, __cstl_slist_node(sl, e));
78 __cstl_slist_insert_after(sl, sl->t, __cstl_slist_node(sl, e));
83 return __cstl_slist_element(sl, __cstl_slist_erase_after(sl, &sl->h));
88 if (sl->t == &sl->h) {
91 return __cstl_slist_element(sl, sl->h.n);
96 if (sl->t == &sl->h) {
99 return __cstl_slist_element(sl, sl->t);
112 while (c->n != NULL) {
121 assert(sl->t->n == NULL);
129 assert(dst->t->n == NULL);
130 dst->t->n = src->h.n;
132 assert(dst->t->n == NULL);
134 dst->count += src->count;
153 _sl[0].count < sl->count / 2;
154 t = t->n, _sl[0].count++)
157 _sl[0].h.n = sl->h.n;
164 _sl[1].count = sl->count - _sl[0].count;
180 if (cmp(__cstl_slist_element(&_sl[0], _sl[0].h.n),
181 __cstl_slist_element(&_sl[1], _sl[1].h.n),
188 __cstl_slist_insert_after(sl, sl->t,
189 __cstl_slist_erase_after(l, &l->h));
207 while (c != NULL && res == 0) {
209 res = visit(__cstl_slist_element(sl, c), p);
224 clr(__cstl_slist_element(sl, h), NULL);
238#define CSTL_SLIST_FIX_SWAP(SL) \
240 if (SL->count == 0) { \
245 CSTL_SLIST_FIX_SWAP(a);
246 CSTL_SLIST_FIX_SWAP(b);
248#undef CSTL_SLIST_FIX_SWAP
263static int cmp_integer(
const void *
const a,
const void *
const b,
267 return ((
struct integer *)a)->v - ((
struct integer *)b)->v;
270static void __test_cstl_slist_free(
void *
const p,
void *
const x)
276static void __test__cstl_slist_fill(
281 for (i = 0; i < n; i++) {
282 struct integer * in = malloc(
sizeof(*in));
294 struct integer a, b, c;
296 a.v = 0; b.v = 1; c.v = 2;
330 static const size_t n = 100;
333 __test__cstl_slist_fill(&sl, n);
342 static const size_t n = 4;
346 __test__cstl_slist_fill(&l1, n);
347 __test__cstl_slist_fill(&l2, n);
358static int cstl_slist_verify_sorted(
void *
const e,
void *
const p)
360 struct integer ** in = p;
363 ck_assert_int_ge(((
struct integer *)e)->v, (*in)->v);
373 static const size_t n = 100;
376 struct integer * in = NULL;
378 __test__cstl_slist_fill(&l, n);
389static int cstl_slist_verify_sorted_rev(
void *
const e,
void *
const p)
391 struct integer ** in = p;
394 ck_assert_int_le(((
struct integer *)e)->v, (*in)->v);
404 static const size_t n = 100;
407 struct integer * in = NULL;
409 __test__cstl_slist_fill(&l, n);
425 __test__cstl_slist_fill(&l1, 0);
432 __test__cstl_slist_fill(&l1, 1);
439 __test__cstl_slist_fill(&l1, 2);
446 __test__cstl_slist_fill(&l1, 2);
447 __test__cstl_slist_fill(&l2, 3);
456Suite * slist_suite(
void)
458 Suite *
const s = suite_create(
"slist");
462 tc = tcase_create(
"slist");
463 tcase_add_test(tc, simple);
464 tcase_add_test(tc, fill);
465 tcase_add_test(tc, concat);
466 tcase_add_test(tc, sort);
467 tcase_add_test(tc, reverse);
468 tcase_add_test(tc, swap);
469 suite_add_tcase(s, tc);
static void cstl_swap(void *const x, void *const y, void *const t, const size_t sz)
Swap values at two memory locations via use of a third.
void cstl_xtor_func_t(void *obj, void *priv)
Type for functions called to construct, clear, or destroy an object.
int cstl_visit_func_t(void *obj, void *priv)
Type for visit callbacks from objects supporting foreach.
int cstl_compare_func_t(const void *obj1, const void *obj2, void *priv)
Function type for comparing (in)equality of two objects.
void * cstl_slist_back(const struct cstl_slist *const sl)
Get a pointer to the last object in the list.
void cstl_slist_insert_after(struct cstl_slist *const sl, void *const e, void *const n)
Insert a new object into the list.
void * cstl_slist_pop_front(struct cstl_slist *const sl)
Remove the first item in the list and return it.
void cstl_slist_clear(struct cstl_slist *const sl, cstl_xtor_func_t *const clr)
Remove objects from and reinitialize a list.
void cstl_slist_reverse(struct cstl_slist *const sl)
Reverse the order of items in the list.
static size_t cstl_slist_size(const struct cstl_slist *sl)
Get the number of objects in the list.
void cstl_slist_sort(struct cstl_slist *const sl, cstl_compare_func_t *const cmp, void *const cmp_p)
Sort the items in a list.
void cstl_slist_push_front(struct cstl_slist *const sl, void *const e)
Insert a new object at the front of the list.
#define DECLARE_CSTL_SLIST(NAME, TYPE, MEMB)
(Statically) declare and initialize a list
void cstl_slist_swap(struct cstl_slist *const a, struct cstl_slist *const b)
Swap the list objects at the two given locations.
int cstl_slist_foreach(struct cstl_slist *const sl, cstl_visit_func_t *const visit, void *const p)
Call a user-supplied function for each object in a list.
void * cstl_slist_front(const struct cstl_slist *const sl)
Get a pointer to the first object in the list.
static void cstl_slist_init(struct cstl_slist *const sl, const size_t off)
Initialize a slist object.
void * cstl_slist_erase_after(struct cstl_slist *const sl, void *const e)
Remove an object from the list.
void cstl_slist_concat(struct cstl_slist *const dst, struct cstl_slist *const src)
Append one list to the end of another.
void cstl_slist_push_back(struct cstl_slist *const sl, void *const e)
Insert a new object at the back of the list.
Node to anchor an element within a list.