#ifndef KIT_ARRAY_REF_H
#define KIT_ARRAY_REF_H

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef i8 (*kit_ar_compare_fn)(void *left, void *right);

i8 kit_ar_equal_bytes(i64 left_element_size, i64 left_size,
                      void *left_data, i64 right_element_size,
                      i64 right_size, void *right_data);

i8 kit_ar_compare(i64 left_element_size, i64 left_size,
                  void *left_data, i64 right_element_size,
                  i64 right_size, void *right_data,
                  kit_ar_compare_fn compare);

#define KIT_AR(type_) \
  struct {            \
    i64    size;      \
    type_ *values;    \
  }

#define KIT_AR_WRAP(name_, element_type_, array_)               \
  struct {                                                      \
    i64            size;                                        \
    element_type_ *values;                                      \
  } name_ = { .size   = (sizeof(array_) / sizeof((array_)[0])), \
              .values = (array_) }

#define KIT_AR_EQUAL(left_, right_)                              \
  kit_ar_equal_bytes(sizeof((left_).values[0]), (left_).size,    \
                     (left_).values, sizeof((right_).values[0]), \
                     (right_).size, (right_).values)

#define KIT_AR_COMPARE(left_, right_, compare_)              \
  kit_ar_compare(sizeof((left_).values[0]), (left_).size,    \
                 (left_).values, sizeof((right_).values[0]), \
                 (right_).size, (right_).values,             \
                 (kit_ar_compare_fn) (compare_))

#ifdef __cplusplus
}
#endif

#ifndef KIT_DISABLE_SHORT_NAMES
#  define ar_compare_fn kit_ar_compare_fn
#  define ar_equal_bytes kit_ar_equal_bytes
#  define ar_compare kit_ar_compare

#  define AR KIT_AR
#  define AR_WRAP KIT_AR_WRAP
#  define AR_EQUAL KIT_AR_EQUAL
#  define AR_COMPARE KIT_AR_COMPARE
#endif

#endif