#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[]; \ } LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE; \ \ static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear( \ LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data) { \ data->len = 0; \ } \ \ static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push( \ LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data, \ ITEM_TYPE value) { \ data->items[data->len++] = value; \ } \ \ static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse( \ LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * restrict src, \ LengthPrefix_##LEN_TYPE##_Array_##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( \ LengthPrefix_##LEN_TYPE##_Array_##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"); \ } #define DEFINE_ALL_LENGTH_PREFIX_ARRAYS(LEN_TYPE) \ DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint8_t) \ DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint16_t) \ DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint32_t) \ DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint64_t) DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint8_t) DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint16_t) DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint32_t) DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint64_t) #define DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, SRC_ITEM_TYPE, DST_ITEM_TYPE) \ static inline int length_prefix_##LEN_TYPE##_array_map_##SRC_ITEM_TYPE##_to_##DST_ITEM_TYPE( \ int (*f)(SRC_ITEM_TYPE const * restrict, DST_ITEM_TYPE * restrict), \ LengthPrefix_##LEN_TYPE##_Array_##SRC_ITEM_TYPE const * restrict src, \ LengthPrefix_##LEN_TYPE##_Array_##DST_ITEM_TYPE * restrict dst) \ { \ if (dst->len < src->len) return -1; /* Ensure enough space */ \ for (LEN_TYPE i = 0; i < src->len; i++) { \ if (f(&src->items[i], &dst->items[i]) != 0) return -1; \ } \ dst->len = src->len; \ return 0; \ } #define DEFINE_ALL_MAPS(LEN_TYPE) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint8_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint16_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint32_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint64_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint8_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint16_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint32_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint64_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint8_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint16_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint32_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint64_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint8_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint16_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint32_t) \ DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint64_t) DEFINE_ALL_MAPS(uint8_t) DEFINE_ALL_MAPS(uint16_t) DEFINE_ALL_MAPS(uint32_t) DEFINE_ALL_MAPS(uint64_t)