#ifndef _array_h_INCLUDED
#define _array_h_INCLUDED

#include "allocate.h"
#include "stack.h"

#define ARRAY(TYPE) \
  struct { \
    TYPE *begin; \
    TYPE *end; \
  }

#define ALLOCATE_ARRAY(A, N) \
  do { \
    const size_t TMP_N = (N); \
    (A).begin = (A).end = \
        kissat_nalloc (solver, TMP_N, sizeof *(A).begin); \
  } while (0)

#define EMPTY_ARRAY EMPTY_STACK
#define SIZE_ARRAY SIZE_STACK

#define PUSH_ARRAY(A, E) \
  do { \
    *(A).end++ = (E); \
  } while (0)

#define REALLOCATE_ARRAY(A, O, N) \
  do { \
    const size_t SIZE = SIZE_ARRAY (A); \
    (A).begin = \
        kissat_nrealloc (solver, (A).begin, (O), (N), sizeof *(A).begin); \
    (A).end = (A).begin + SIZE; \
  } while (0)

#define RELEASE_ARRAY(A, N) \
  do { \
    const size_t TMP_NIZE = (N); \
    DEALLOC ((A).begin, TMP_NIZE); \
  } while (0)

#define CLEAR_ARRAY CLEAR_STACK
#define TOP_ARRAY TOP_STACK
#define PEEK_ARRAY PEEK_STACK
#define POKE_ARRAY POKE_STACK
#define POP_ARRAY POP_STACK
#define BEGIN_ARRAY BEGIN_STACK
#define END_ARRAY END_STACK
#define RESIZE_ARRAY RESIZE_STACK
#define SET_END_OF_ARRAY SET_END_OF_STACK

// clang-format off

typedef ARRAY (unsigned) unsigned_array;

// clang-format on

#endif
