#pragma once

#include <stdio.h>
#include <stdint.h>

#define DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, ITEM_TYPE)                        \
    typedef struct {                                                           \
        LEN_TYPE len;                                                          \
        ITEM_TYPE items[];                                                     \
    } __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_;                             \
                                                                               \
    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear(   \
        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                   \
        data->len = 0;                                                         \
    }                                                                          \
                                                                               \
    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push(    \
        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                     \
        ITEM_TYPE value) {                                                     \
        data->items[data->len++] = value;                                      \
    }                                                                          \
                                                                               \
    static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse(  \
        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src,      \
        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) {           \
        for (LEN_TYPE i = 0; i < src->len; i++) {                              \
            dst->items[i] = src->items[src->len - 1 - i];                      \
        }                                                                      \
        dst->len = src->len;                                                   \
        return 0;                                                              \
    }                                                                          \
                                                                               \
    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump(    \
        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {            \
        printf("Length: %llu\n", (unsigned long long) data->len);              \
        for (LEN_TYPE i = 0; i < data->len; i++) {                             \
            printf("%llu ", (unsigned long long) data->items[i]);              \
        }                                                                      \
        printf("\n");                                                          \
    }