[ create a new paste ] login | about

Link: http://codepad.org/Cf5zh5xS    [ raw code | output | fork ]

C, pasted on Jul 5:
/*
 * (C) Shao Miller, 2010
 *
 * Translation-time type information.
 * At the cost of each wrapper type being >= sizeof(char*)
 */
#include <stddef.h>
#include <stdio.h>

enum types {
  types_none,
  types_char,
  types_short,
  types_int,
  types_long,
  types_total
};

union char_wrapper;
typedef char (*char_func_type)(union char_wrapper *this);

union short_wrapper;
typedef short (*short_func_type)(union short_wrapper *this);

/* etc. */

union char_wrapper {
  char value;
  char (*type)[types_char];
  char_func_type func[1];
};

union short_wrapper {
  short value;
  char (*type)[types_short];
  short_func_type func[1];
};

/* etc. */

/* This matches char_func_type */
char char_func(union char_wrapper *this) {
  puts("char_func()");
  return this->value;
}

/* This matches short_func_type */
short short_func(union short_wrapper *this) {
  puts("short_func()");
  return this->value;
}

/* etc. */

union any_func {
  char_func_type char_func;
  short_func_type short_func;
  /* etc. */
};

union any_func funcs[types_total];

void init_funcs(void) {
  funcs[types_char].char_func = char_func;
  funcs[types_short].short_func = short_func;
  /* etc. */
}

#define func(x) \
\
(*(x.func - ((char**)x.func - (char**)funcs) + sizeof(*x.type)))(&x)

int main(void) {
  union char_wrapper foo;
  char foo_test;
  union short_wrapper bar;
  short bar_test;

  init_funcs();

  if (sizeof(*foo.type) == types_char) {
    puts("foo was indeed a char_wrapper");
  }
  if (sizeof(*bar.type) == types_short) {
    puts("bar was indeed a short_wrapper");
  }

  foo_test = func(foo);
  bar_test = func(bar);

  return 0;
}


Output:
1
2
3
4
foo was indeed a char_wrapper
bar was indeed a short_wrapper
char_func()
short_func()


Create a new paste based on this one


Comments: