#ifndef ALIST_H
#define ALIST_H

// An alist functions as a dynamically allocated resizeable
// array. The item type is void * so it can store pointers
// to items of any type.

typedef struct alist alist;

#define INITIAL_CAPACITY 5

// Creates a new alist of size 5.
// If memory allocation fails, returns NULL.
alist *alist_new();

// Frees the memory for at. Does not free any dynamically
// allocated memory for the items in a.
void alist_free(alist *a);

// Returns the length of a.
size_t alist_length(alist *a);

// Returns the item in a in position index which
// must be less than the length of a.
void *alist_get(alist *a, size_t index);

// Sets the value of the item in a in position
// index which must be less than the length of a.
void alist_put(alist *a, size_t index, void *value);

// Appends a new item to the end of a. Returns a. If
// memory allocation fails, leaves a unchanged and
// returns NULL.
alist *alist_append(alist *a, void *value);

// Removes the item from a in position index
// which must be less than the length of a. Items
// to the right of position index are shifted left.
void alist_remove(alist *a, size_t index);

// Inserts an item into a at position index which
// must be less than or equal to the length of a.
// Items from position index to the right are shifted right.
alist *alist_insert(alist *a, size_t index, void *value);

// Returns a dynamically allocated array containing
// (the pointers to) the items in a.
void **alist_to_array(alist *a);

// Returns an alist containing (the pointers to) the items
// in array of size n.
alist *alist_new_from_array(int n, void *array[n]);

// Iterates over the items in a calling func on each item in a.
void alist_iterate(alist *a, void (*func)(void *));

#endif
