+#ifdef ARRAY_USE_TALLOC
+#include <ccan/talloc/talloc.h>
+#endif
+
+#ifndef HAVE_ATTRIBUTE_MAY_ALIAS
+#define HAVE_ATTRIBUTE_MAY_ALIAS 1
+#endif
+
+//Use the array_alias macro to indicate that a pointer has changed but strict aliasing rules are too stupid to know it
+#if HAVE_ATTRIBUTE_MAY_ALIAS==1
+#define array_alias(ptr) /* nothing */
+#define array(type) struct {type *item; size_t size; size_t alloc;} __attribute__((__may_alias__))
+#else
+#define array_alias(ptr) qsort(ptr, 0, 1, array_alias_helper) //hack
+#define array(type) struct {type *item; size_t size; size_t alloc;}
+#endif
+
+//We call allocator functions directly
+#ifndef ARRAY_USE_TALLOC
+
+#define array_new() {0,0,0}
+#define array_init(array) do {(array).item=0; (array).size=0; (array).alloc=0;} while(0)
+#define array_realloc(array, newAlloc) do {(array).item = realloc((array).item, ((array).alloc = (newAlloc))*sizeof(*(array).item));} while(0)
+#define array_free(array) do {free((array).item);} while(0)
+
+#else
+
+//note: the allocations are given an extra byte to prevent free (and thus loss of ctx) on realloc to size 0
+
+#define array_new(ctx) {talloc_size(ctx,1), 0,0}
+#define array_init(array, ctx) do {(array).item=talloc_size(ctx,1); (array).size=0; (array).alloc=0;} while(0)
+#define array_realloc(array, newAlloc) do {(array).item = talloc_realloc_size(NULL, (array).item, ((array).alloc = (newAlloc))*sizeof(*(array).item) +1);} while(0)
+#define array_free(array) do {talloc_free((array).item);} while(0)
+
+#endif
+
+
+//We call helper functions
+#define array_resize(array, newSize) do {(array).size = (newSize); if ((array).size > (array).alloc) { array_resize_helper((array_char*)&(array), sizeof(*(array).item)); array_alias(&(array));}} while(0)
+#define array_resize0(array, newSize) do {array_resize0_helper((array_char*)&(array), sizeof(*(array).item), newSize);} while(0)
+#define array_prepend_lit(array, stringLiteral) do {array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, stringLiteral, sizeof(stringLiteral)-1, 1); array_alias(&(array)); (array).item[--(array).size] = 0;} while(0)
+#define array_prepend_string(array, str) do {const char *__str = (str); size_t __len = strlen(__str); array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, __str, __len, 1); array_alias(&(array)); (array).item[--(array).size] = 0;} while(0)
+#define array_prepend_items(array, items, count) do {array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, items, count, 0); array_alias(&(array));} while(0)
+
+
+//We call other array_* macros
+#define array_from_c(array, c_array) array_from_items(array, c_array, sizeof(c_array)/sizeof(*(c_array)))
+#define array_from_lit(array, stringLiteral) do {array_from_items(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0)
+#define array_from_string(array, str) do {const char *__str = (str); array_from_items(array, __str, strlen(__str)+1); (array).size--;} while(0)
+#define array_from_items(array, items, count) do {size_t __count = (count); array_resize(array, __count); memcpy((array).item, items, __count*sizeof(*(array).item));} while(0)
+#define array_append(array, ...) do {array_resize(array, (array).size+1); (array).item[(array).size-1] = (__VA_ARGS__);} while(0)
+#define array_append_string(array, str) do {const char *__str = (str); array_append_items(array, __str, strlen(__str)+1); (array).size--;} while(0)
+#define array_append_lit(array, stringLiteral) do {array_append_items(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0)
+#define array_append_items(array, items, count) do {size_t __count = (count); array_resize(array, (array).size+__count); memcpy((array).item+(array).size-__count, items, __count*sizeof(*(array).item));} while(0)
+#define array_prepend(array, ...) do {array_resize(array, (array).size+1); memmove((array).item+1, (array).item, ((array).size-1)*sizeof(*(array).item)); *(array).item = (__VA_ARGS__);} while(0)
+#define array_push(array, ...) array_append(array, __VA_ARGS__)
+#define array_pop_check(array) ((array).size ? array_pop(array) : NULL)
+
+#define array_growalloc(array, newAlloc) do {size_t __newAlloc=(newAlloc); if (__newAlloc > (array).alloc) array_realloc(array, (__newAlloc+63)&~63); } while(0)