Created
October 19, 2020 03:29
-
-
Save aakropotkin/6550d892338626964a870e408d1e8912 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 <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