template_H.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #pragma once
  2. // https://gist.github.com/hlorenzi/8ce4184f8416665002a5
  3. template <typename TReturn, typename... TArgs>
  4. class Callback
  5. {
  6. public:
  7. template <typename TObject, TReturn(TObject::* member_function)(TArgs...)>
  8. static Callback<TReturn, TArgs...> make_member(TObject* user_data)
  9. {
  10. Callback<TReturn, TArgs...> callback;
  11. callback.user_data = (void*)user_data;
  12. callback.wrapped_call = wrapped_member_call<TObject, member_function>;
  13. return callback;
  14. }
  15. template <typename TObject, TReturn(*static_function)(TObject*, TArgs...)>
  16. static Callback<TReturn, TArgs...> make_userdata(TObject* user_data)
  17. {
  18. Callback<TReturn, TArgs...> callback;
  19. callback.user_data = (void*)user_data;
  20. callback.wrapped_call = wrapped_userdata_call<TObject, static_function>;
  21. return callback;
  22. }
  23. template <TReturn(*static_function)(TArgs...)>
  24. static Callback<TReturn, TArgs...> make_static()
  25. {
  26. Callback<TReturn, TArgs...> callback;
  27. callback.user_data = nullptr;
  28. callback.wrapped_call = wrapped_static_call<static_function>;
  29. return callback;
  30. }
  31. TReturn call(TArgs... args)
  32. {
  33. return this->wrapped_call(this->user_data, args...);
  34. }
  35. protected:
  36. TReturn(*wrapped_call)(void*, TArgs...);
  37. void* user_data;
  38. template <typename TObject, TReturn(TObject::* member_function)(TArgs...)>
  39. static TReturn wrapped_member_call(void* user_data, TArgs... args)
  40. {
  41. return (((TObject*)user_data)->*member_function)(args...);
  42. }
  43. template <typename TObject, TReturn(*static_function)(TObject*, TArgs...)>
  44. static TReturn wrapped_userdata_call(void* user_data, TArgs... args)
  45. {
  46. return static_function((TObject*)user_data, args...);
  47. }
  48. template <TReturn(*static_function)(TArgs...)>
  49. static TReturn wrapped_static_call(void* user_data, TArgs... args)
  50. {
  51. return static_function(args...);
  52. }
  53. };