Last active
July 27, 2020 08:21
-
-
Save trya/4ccc8d1f07b320c73665fd2579845d5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include <string.h> | |
#include <stdint.h> | |
typedef struct fixed_point { | |
long long i; // integer part | |
unsigned long long d; // decimal part | |
} fixed_point; | |
#define DEFINE_ARRAY_TYPE(T) \ | |
typedef struct array_ ## T { size_t sz; T d[]; } array_ ## T; \ | |
void array_print_ ## T (const array_ ## T *a) \ | |
{ \ | |
printf("{ "); \ | |
if (a->sz > 0) print_ ## T (&a->d[0]); \ | |
for (size_t i = 1; i < a->sz; i++) { \ | |
printf(", "); \ | |
print_ ## T (&a->d[i]); \ | |
} \ | |
printf(" }\n"); \ | |
} \ | |
array_ ## T * array_ ## T ## _new(size_t n) \ | |
{ \ | |
array_ ## T *a = malloc(sizeof(array_ ## T) + sizeof(T[n])); \ | |
if (a) a->sz = n; \ | |
return a; \ | |
} \ | |
array_ ## T * array_ ## T ## _new_zero(size_t n) \ | |
{ \ | |
array_ ## T *a = calloc(sizeof(array_ ## T) + sizeof(T[n]), 1); \ | |
if (a) a->sz = n; \ | |
return a; \ | |
} \ | |
array_ ## T * array_ ## T ## _new_init(size_t n, size_t m, const T v[m]) \ | |
{ \ | |
array_ ## T *a = array_ ## T ## _new(n); \ | |
if (a) { \ | |
size_t i; \ | |
for (i = 0; i < m; i++) a->d[i] = v[i]; \ | |
if (i < n) memset(a->d+i, 0, sizeof(T)*(n-m)); \ | |
} \ | |
return a; \ | |
} | |
#define ARRAY(T, ...) (T []){ __VA_ARGS__ } | |
#define ARRAY_SZ(a) (sizeof((a))/sizeof((a)[0])) | |
#define ARRAY_NEW(T, sz) array_ ## T ## _new((sz)) | |
#define ARRAY_NEW_INIT(T, sz, a) array_ ## T ## _new_init(sz, ARRAY_SZ((a)), (a)) | |
#define ARRAY_NEW_COPY(T, a) array_ ## T ## _new_init(ARRAY_SZ((a)), ARRAY_SZ((a)), (a)) | |
#define print_format(x) _Generic((x), \ | |
char: "%c", \ | |
int: "%d", \ | |
float: "%f", \ | |
double: "%f", \ | |
default: "unknown_type") | |
#define GEN_PRINT_FUNC(T) \ | |
void print_ ## T (const T *x) \ | |
{ \ | |
printf(print_format(*(x)), *(x)); \ | |
} | |
#define SUPPORTED_ARRAY_TYPES(X) \ | |
X(char) \ | |
X(int) \ | |
X(float) \ | |
X(double) \ | |
X(fixed_point) | |
GEN_PRINT_FUNC(char) | |
GEN_PRINT_FUNC(int) | |
GEN_PRINT_FUNC(float) | |
GEN_PRINT_FUNC(double) | |
void print_fixed_point(const fixed_point *fp) | |
{ | |
printf("%lld.%llu", fp->i, fp->d); | |
} | |
SUPPORTED_ARRAY_TYPES(DEFINE_ARRAY_TYPE) | |
void array_print_default(void *p) { puts("unknown_array_type"); } | |
#define array_print_LIST(T) \ | |
array_ ## T *: array_print_ ## T, \ | |
const array_ ## T *: array_print_ ## T, | |
#define array_print(a) _Generic((a), \ | |
SUPPORTED_ARRAY_TYPES(array_print_LIST) \ | |
default: array_print_default)((a)) | |
void print_string(const array_char *s) | |
{ | |
printf("%s\n", s->d); | |
} | |
int main(void) | |
{ | |
array_char *s = ARRAY_NEW_COPY(char, "ebin"); | |
array_int *i = ARRAY_NEW_COPY(int, ARRAY(int, 1, 2, 3)); | |
array_float *f = ARRAY_NEW_COPY(float, ARRAY(float, 100, INFINITY, NAN)); | |
array_double *d = ARRAY_NEW_COPY(double, ARRAY(double, 333.333, 222.222, 111.111)); | |
array_fixed_point *fp = ARRAY_NEW_COPY(fixed_point, ARRAY(fixed_point, {1,234}, {90,2143})); | |
array_print(s); | |
print_string(s); | |
array_print(i); | |
array_print(f); | |
array_print(d); | |
array_print(fp); | |
int i2[] = { 3, 2, 1 }; | |
memcpy(i->d, &i2, sizeof(i2)); | |
array_print(i); | |
array_int *i3 = ARRAY_NEW_INIT(int, 4, ARRAY(int, 123, 234, 345)); | |
array_print(i3); | |
array_int *i4 = array_int_new_zero(10); | |
array_print(i4); | |
array_int *i5 = array_int_new(0); | |
array_print(i5); | |
array_int *i6 = ARRAY_NEW_INIT(int, 4, ARRAY(int, 123, 234, 345, 456, 567)); | |
array_print(i6); | |
free(s); | |
free(i); | |
free(f); | |
free(d); | |
free(fp); | |
free(i3); | |
free(i4); | |
free(i5); | |
free(i6); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment