meh edited this page May 19, 2011 · 3 revisions
Clone this wiki locally

Example usage:

typedef struct {
    int a, b, c;
} MyStruct;

#define MyStructFreer(x) free(x->data)

KLIST_INIT(lms, MyStruct, MyStructFreer);

klist_t(lms) myList = kl_init(lms);

MyStruct *a, *b, *c;
a = calloc(1, sizeof(MyStruct));
b = calloc(1, sizeof(MyStruct));

*kl_pushp(lms, myList) = a;
*kl_pushp(lms, myList) = b;

kl_shift(lms, myList, &c);

kl_destroy(lms, myList);


KLISTINIT(name, kltype_t, kmpfree_t)
name = some name to use when referring to lists of this type
kltype_t = the type to store in the list, either eg 'int' or 'MyStruct' the pointer form
kmpfree_t = the custom freeing function. Only used when destroying. Will get passed a kliter. This should
probably free the 'data' object, because it's probably a MyStruct*
However, if you're freeing your objects as you 'pop' them from the list, then you don't want this,
because this will get called on the objects in the mem pool at destruct time, after you've already freed them
creates a mempool for the iterator structs: KMEMPOOL_INIT(name, kl1##name, kmpfreet) 

The structures

kliter_t(name) = // The struct for a single item in the list

struct __kl1##name {
    kltypet data;             // The data at this point in the list
    struct __kl1##name *next; // The next point
klistt(name) = // The actual list structure

typedef struct {
    kl1##name head, *tail; // First and last in the list
    kmp##name##_t *mp; // The mempool
    size_t size; // Number of items in the list for your reference
} kl##name##_t;

The macros

creates and returns a new klist_t(name)
creates the mempool in mp
creates a new iterator (using the mempool), sets both head and tail to it
sets the head/tail iterator's next to zero
kl_destroy(name, kl) 
frees all the items in the list
destroys the mempool, WHICH CALLS THE FREE-ER on all iterator struct pointers, which should probably
free the MyStruct
However, it'll also call the freer on all the pooled iterator structs, which were probably already freed when you pop'd them
Its probably worth popping everything and freeing them all before calling this, and making its freer do nothing fancy.
frees the list
kl_pushp(name, kl) 
Adds a new item. Returns the previous tail value, which you can use to set the value.
Makes a new list node:
Next is 0
Makes it the new 'tail'
Makes the old tail point to the new node as it's 'next' 
returns a pointer to the last tails data (kltype_t*)
kl_shift(name, kl, d)
Gets the first item (head) from the list
Stores it in 'd'
Returns 0 if ok, or -1 if the list is empty