fork download
  1. #include <iostream>
  2.  
  3. class Null { };
  4.  
  5. #define DELEGATE(returnType, ...) Delegate<returnType (*)(__VA_ARGS__), returnType (Null::*)(__VA_ARGS__)>
  6. #define ARGS(...) __VA_ARGS__
  7.  
  8. template<class _FunctionType, class _MemberType>
  9. struct Delegate {
  10. typedef _FunctionType FunctionType;
  11. typedef _MemberType MemberType;
  12.  
  13. Null* mpThis;
  14. union DelPtr {
  15. _FunctionType asStatic;
  16. _MemberType asMember;
  17. DelPtr(_FunctionType p) : asStatic(p) { }
  18. DelPtr(_MemberType p) : asMember(p) { }
  19. };
  20. DelPtr mpfn;
  21.  
  22. Delegate(_FunctionType pfn) : mpThis(NULL), mpfn(pfn) { }
  23. Delegate(_MemberType pfn, void* pThis) : mpThis((Null*)pThis), mpfn(pfn) { }
  24. };
  25.  
  26. #define INVOKE(_delegate, ...) ( \
  27. (_delegate).mpThis ? \
  28. (((_delegate).mpThis)->*((_delegate).mpfn.asMember))(__VA_ARGS__) \
  29. : \
  30. ((_delegate).mpfn.asStatic)(__VA_ARGS__) \
  31. )
  32.  
  33.  
  34. float test1(int a, int b) {
  35. std::cout << "a:" << a << std::endl;
  36. std::cout << "b:" << b << std::endl;
  37. return 7.0f;
  38. }
  39.  
  40. class TestClass {
  41. public:
  42. double x;
  43. float test2(int a, int b) {
  44. std::cout << "TestClass a:" << a << std::endl;
  45. std::cout << "TestClass b:" << b << std::endl;
  46. std::cout << "TestClass x:" << x << std::endl;
  47. return 5.0f;
  48. }
  49. };
  50.  
  51. class TestClass2 {
  52. public:
  53. char c;
  54. float test3(int a, int b) {
  55. std::cout << "TestClass2 a:" << a << std::endl;
  56. std::cout << "TestClass2 b:" << b << std::endl;
  57. std::cout << "TestClass2 c:" << c << std::endl;
  58. return 3.0f;
  59. }
  60. };
  61.  
  62. // Declare MANUALLY
  63. // typedef float (*FnStatic)(int, int) ;
  64. // typedef float (NullClass::*FnMember)(int, int);
  65. // typedef Delegate<FnStatic, FnMember> Delegate1;
  66.  
  67. // Declare using DELEGATE macro
  68. typedef DELEGATE(float, ARGS(int, int)) Delegate1;
  69.  
  70. int main() {
  71. TestClass obj;
  72. obj.x = 23.3;
  73. TestClass2 obj2;
  74. obj2.c = 'h';
  75.  
  76. std::cout << "test\n";
  77.  
  78. Delegate1 d = Delegate1(test1);
  79. Delegate1 e = Delegate1((Delegate1::MemberType)&TestClass::test2, &obj);
  80. Delegate1 f = Delegate1((Delegate1::MemberType)&TestClass2::test3, &obj2);
  81.  
  82. std::cout << "d return value: " << (INVOKE(d, ARGS(5, 6))) << std::endl;
  83. std::cout << "e return value: " << (INVOKE(e, ARGS(8, 9))) << std::endl;
  84. std::cout << "f return value: " << (INVOKE(f, ARGS(1, 2))) << std::endl;
  85.  
  86. int x;
  87. std::cin >> x;
  88. return 0;
  89. }
Success #stdin #stdout 0.01s 2688KB
stdin
Standard input is empty
stdout
test
a:5
b:6
d return value: 7
TestClass a:8
TestClass b:9
TestClass x:23.3
e return value: 5
TestClass2 a:1
TestClass2 b:2
TestClass2 c:h
f return value: 3