Skip to content

Instantly share code, notes, and snippets.

@aakropotkin
Created October 19, 2020 03:29
Show Gist options
  • Save aakropotkin/6550d892338626964a870e408d1e8912 to your computer and use it in GitHub Desktop.
Save aakropotkin/6550d892338626964a870e408d1e8912 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
/* Type Compatibility */
#define is_compatibleT(_CX, _CT) _Generic((_CX), _CT:1, default: 0)
#define is_compatibleV(_C2X, _C2V) is_compatibleT (_C2X, typeof (_C2V))
#define ensure_type(_EP, _ET) _Static_assert(is_compatible(_EP, _ET), \
"incorrect type for parameter '" #_EP "', expected " #_ET)
/* Generic Prints */
#define printf_dec_format(x) _Generic ((x), \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
signed short: "%hd", \
unsigned short: "%hu", \
signed int: "%d", \
unsigned int: "%u", \
long int: "%ld", \
unsigned long int: "%lu", \
long long int: "%lld", \
unsigned long long int: "%llu", \
float: "%f", \
double: "%f", \
long double: "%Lf", \
char *: "%s", \
void *: "%p")
#define print(x) printf (printf_dec_format (x), x)
#define printnl(x) printf (printf_dec_format (x), x), printf ("\n");
/* Get the name of a type */
#define typename(x) _Generic ((x), _Bool: "_Bool", \
char: "char", \
signed char: "signed char", \
unsigned char: "unsigned char", \
const char: "const char", \
short int: "short int", \
unsigned short int: "unsigned short int", \
int: "int", \
unsigned int: "unsigned int", \
long int: "long int", \
unsigned long int: "unsigned long int", \
long long int: "long long int", \
unsigned long long int: "unsigned long long int", \
float: "float", \
double: "double", \
long double: "long double", \
char *: "pointer to char", \
void *: "pointer to void", \
int *: "pointer to int", \
default: "other")
void
test_typename (void)
{
size_t s;
ptrdiff_t p;
intmax_t i;
int ai[3] = {0};
const short sh = 10;
printf ("size_t is '%s'\n", typename (s));
printf ("ptrdiff_t is '%s'\n", typename (p));
printf ("intmax_t is '%s'\n", typename (i));
printf ("character constant is '%s'\n", typename ('0'));
printf ("0x7FFFFFFF is '%s'\n", typename (0x7FFFFFFF));
printf ("0xFFFFFFFF is '%s'\n", typename (0xFFFFFFFF));
printf ("0x7FFFFFFFU is '%s'\n", typename (0x7FFFFFFFU));
printf ("array of int is '%s'\n", typename (ai));
printf ("short constant is '%s'\n", typename (sh));
}
void
test_equality (void)
{
enum e { E1 };
bool ei = is_compatibleT (E1, int);
printf ("%s e :==: int\n", ei ? "True":"False");
}
int
main (int argc, char *argv[], char **env)
{
test_typename ();
test_equality ();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment