fork download
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <functional>
  4.  
  5. // C library with some callbacks
  6.  
  7. typedef void (*CallbackTypeOne)(void* userdata, double arg1);
  8. typedef void (*CallbackTypeTwo)(void* userdata, int arg1);
  9. typedef void (*CallbackTypeThree)(void* userdata, int arg1, float arg2);
  10.  
  11. typedef void(*GenericCallback)();
  12.  
  13. void registerAndCallCallback(int typeID, GenericCallback callback, void* userdata)
  14. {
  15. switch (typeID) {
  16. case 0: ((CallbackTypeOne)callback)(userdata, 3.14); break;
  17. case 1: ((CallbackTypeTwo)callback)(userdata, 42); break;
  18. case 2: ((CallbackTypeThree)callback)(userdata, 42, 3.14f); break;
  19. };
  20. }
  21.  
  22. // C++ app using the above library
  23.  
  24. template <const size_t TypeID, typename T, typename RetType, typename... Args>
  25. struct FunctionFactory
  26. {
  27. public:
  28. static void bind(RetType(T::*f)(Args...)) {
  29. instance().fn_ = [f](T* t, Args&&... args) {
  30. return (t->*f)(std::forward<Args>(args)...);
  31. };
  32. }
  33.  
  34. static RetType invoke(void* userdata, Args... args) {
  35. T * t = reinterpret_cast<T*>(userdata);
  36. return instance().fn_(t, args...);
  37. }
  38.  
  39. typedef decltype(&FunctionFactory::invoke) pointer_type;
  40. static pointer_type ptr() {
  41. return &invoke;
  42. }
  43.  
  44. private:
  45. static FunctionFactory & instance() {
  46. static FunctionFactory inst_;
  47. return inst_;
  48. }
  49.  
  50. FunctionFactory() = default;
  51.  
  52. std::function<RetType(T*, Args...)> fn_;
  53. };
  54.  
  55. template <const size_t TypeID, typename T, typename RetType, typename... Args>
  56. typename FunctionFactory<TypeID, T, RetType, Args...>::pointer_type
  57. getFunctionPtr(RetType(T::*f)(Args...))
  58. {
  59. FunctionFactory<TypeID, T, RetType, Args...>::bind(f);
  60. return FunctionFactory<TypeID, T, RetType, Args...>::ptr();
  61. }
  62.  
  63. class MyClass
  64. {
  65. public:
  66. MyClass() {
  67. registerAndCallCallback(0, reinterpret_cast<GenericCallback>(getFunctionPtr<0>(&MyClass::callbackOne)), this);
  68. registerAndCallCallback(1, reinterpret_cast<GenericCallback>(getFunctionPtr<1>(&MyClass::callbackTwo)), this);
  69. registerAndCallCallback(2, reinterpret_cast<GenericCallback>(getFunctionPtr<2>(&MyClass::callbackThree)), this);
  70. }
  71.  
  72. void callbackOne(double arg1) { std::cout << "callback 1 called: " << arg1 << std::endl; }
  73. void callbackTwo(int arg1) { std::cout << "callback 2 called: " << arg1 << std::endl; }
  74. void callbackThree(int arg1, float arg2) { std:: cout << "callback 3 called: " << arg1 << ", " << arg2 << std::endl; }
  75. };
  76.  
  77. int main()
  78. {
  79. MyClass myclass;
  80. return 0;
  81. }
  82.  
Success #stdin #stdout 0s 4396KB
stdin
Standard input is empty
stdout
callback 1 called: 3.14
callback 2 called: 42
callback 3 called: 42, 3.14