Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.67 KB | None | 0 0
  1. #pragma once
  2. #include <functional>
  3. #include <any>
  4.  
  5. template <class T>
  6. struct fn_signature
  7. : fn_signature<decltype(std::function(std::declval<T>()))>
  8. { };
  9.  
  10. template <class T>
  11. struct fn_signature<std::function<T>> : fn_signature<T>
  12. { };
  13.  
  14. template <class R, class... Args>
  15. struct fn_signature<R(Args...)>
  16. {
  17. using return_type = R;
  18. using type = R(Args...);
  19.  
  20. template <class T>
  21. using set_rtype = T(Args...);
  22. };
  23.  
  24. // Any value auto cast
  25. struct any_value : std::any
  26. {
  27. using std::any::any;
  28.  
  29. template <class T>
  30. operator T() {
  31. return std::any_cast<T>(*this);
  32. }
  33. };
  34.  
  35. // std::any or void will accept any function
  36. template <class R = any_value>
  37. struct any_function
  38. {
  39. any_function() = default;
  40.  
  41. template <class F>
  42. any_function(F&& fn)
  43. {
  44. using fn_sign = fn_signature<F>;
  45. using cast_sign = typename fn_sign::template set_rtype<R>;
  46.  
  47. fn_ = std::function<cast_sign>([fn = std::forward<F>(fn)](auto&&... args) -> R
  48. {
  49. if constexpr (std::is_same_v<R, void>)
  50. fn(std::forward<decltype(args)>(args)...);
  51. else if constexpr (std::is_same_v<typename fn_sign::return_type, void>) {
  52. fn(std::forward<decltype(args)>(args)...);
  53. return { };
  54. }
  55. else
  56. return fn(std::forward<decltype(args)>(args)...);
  57. });
  58. }
  59.  
  60. template <class... Args>
  61. R operator()(Args&&... args) const
  62. {
  63. using fn_type = std::function<R(Args...)>;
  64. if (auto fn = std::any_cast<fn_type>(&fn_))
  65. return (*fn)(std::forward<Args>(args)...);
  66. else
  67. throw std::bad_function_call();
  68. }
  69.  
  70. private:
  71. std::any fn_;
  72. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement