fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4.  
  5. typedef int abstract_func_type ();
  6.  
  7. typedef struct htentry {
  8. struct htentry *next;
  9. abstract_func_type *k;
  10. abstract_func_type **fpp;
  11. } htentry;
  12. static htentry *hashtable[101];
  13.  
  14. static void insert (abstract_func_type *k, abstract_func_type **p) {
  15. htentry *e = malloc(sizeof(htentry));
  16. int i = ((char *)k - (char *)0) % 101;
  17. e->k = k;
  18. e->fpp = p;
  19. e->next = hashtable[i];
  20. hashtable[i] = e;
  21. }
  22.  
  23. static abstract_func_type ** lookup (abstract_func_type *k) {
  24. int i = ((char *)k - (char *)0) % 101;
  25. htentry *e = hashtable[i];
  26. while (e) {
  27. if (e->k == k) return e->fpp;
  28. e = e->next;
  29. }
  30. return 0;
  31. }
  32.  
  33. abstract_func_type * abstract_func_get (abstract_func_type *k) {
  34. abstract_func_type **f = lookup(k);
  35. if (f) return *f;
  36. return 0;
  37. }
  38.  
  39. int abstract_func_set (abstract_func_type *k, abstract_func_type *p) {
  40. abstract_func_type **f = lookup(k);
  41. if (f) {
  42. *f = p;
  43. return 0;
  44. }
  45. return -ENOENT;
  46. }
  47.  
  48. #define DEFINE_ABSTRACT_FUNC(func) \
  49.   static int static_##func (); \
  50.   static abstract_func_type *func##_ptr = static_##func; \
  51.   int func () { return func##_ptr(); } \
  52.   static int static_##func ()
  53.  
  54. DEFINE_ABSTRACT_FUNC(foo) { return puts("foo"); }
  55. DEFINE_ABSTRACT_FUNC(bar) { return puts("bar"); }
  56.  
  57. void abstract_func_init () {
  58. insert(foo, &foo_ptr);
  59. insert(bar, &bar_ptr);
  60. }
  61.  
  62. void swap(abstract_func_type *a, abstract_func_type *b) {
  63. abstract_func_type *ap = abstract_func_get(a);
  64. abstract_func_type *bp = abstract_func_get(b);
  65. abstract_func_set(a, bp);
  66. abstract_func_set(b, ap);
  67. }
  68.  
  69. int
  70. main ()
  71. {
  72. abstract_func_init();
  73. puts("before swap");
  74. foo();
  75. bar();
  76. swap(foo, bar);
  77. puts("after swap");
  78. foo();
  79. bar();
  80. return 0;
  81. }
  82.  
Success #stdin #stdout 0s 1964KB
stdin
Standard input is empty
stdout
before swap
foo
bar
after swap
bar
foo