#ifndef __array_h
#define __array_h

#include <stddef.h>
#include <assert.h>

#define BucketShift	5
#define BucketSize	(1 << BucketShift)
#define ElementMask	(BucketSize - 1)

typedef struct array  *array_t;
typedef struct bucket *bucket_t;

struct bucket
{
  void		*elements[32];
};

struct array
{
  bucket_t	*buckets;
  size_t	 capacity;
};

extern void    array_defaultElement_(void *element);
extern array_t array_new(size_t size);
extern void    array_free(array_t self);
extern array_t array_grow(array_t array, size_t index);
extern void   *array_uncheckedAt_put_(array_t array, size_t index, void *element);
extern void   *array_at_put_(array_t array, size_t index, void *element);

static inline void *array_uncheckedAt_(array_t array, size_t index)
{
  return array->buckets[index >> BucketShift]->elements[index & ElementMask];
}

static inline void *array_at_(array_t array, size_t index)
{
  return (index < array->capacity) ? array_uncheckedAt_(array, index) : 0;
}

#endif /* __array_h */
