fork(1) download
  1. #include <iostream>
  2. #include <memory>
  3.  
  4. struct function
  5. {
  6. struct base
  7. {
  8. virtual void call() = 0;
  9. virtual base* clone() = 0;
  10. };
  11.  
  12. template <typename Fn>
  13. struct impl : base
  14. {
  15. Fn fn_;
  16.  
  17. impl(Fn&& fn) : fn_(std::forward<Fn>(fn)){}
  18. impl(Fn& fn) : fn_(fn){}
  19.  
  20. virtual void call()
  21. {
  22. fn_();
  23. }
  24.  
  25. virtual base* clone() { return new impl<Fn>(fn_); }
  26.  
  27. };
  28.  
  29. base* holder_;
  30.  
  31. function() : holder_(nullptr)
  32. {};
  33.  
  34. template <typename Fn>
  35. function(Fn&& fn) : holder_(nullptr)
  36. {
  37.  
  38. holder_ = new impl<Fn>(std::forward<Fn>(fn));
  39. }
  40.  
  41. function( function&& other)
  42. {
  43. holder_ = other.holder_;
  44. other.holder_ = nullptr;
  45.  
  46. }
  47.  
  48. function(const function& other)
  49. {
  50. holder_ = other.holder_->clone();
  51. }
  52. ~function()
  53. {
  54. if (holder_) delete holder_;
  55. }
  56.  
  57.  
  58. function& operator=(function&& other)
  59. {
  60. if (holder_) delete holder_;
  61. holder_ = other.holder_;
  62. other.holder_ = nullptr;
  63. return *this;
  64. }
  65.  
  66. function& operator=(const function& other)
  67. {
  68. if (holder_) delete holder_;
  69. holder_ = other.holder_->clone();
  70.  
  71. return *this;
  72. }
  73.  
  74. void operator()()
  75. {
  76. holder_->call();
  77. }
  78. };
  79.  
  80.  
  81. class Gpio
  82. {
  83. public:
  84. using ExtiHandler = function;
  85. //private:
  86. ExtiHandler handler;
  87. //public:
  88. void enable_irq(ExtiHandler handler_in)
  89. {
  90. // enable interrupt
  91. // ...
  92. // save handler so callback can be issued later
  93. handler = handler_in;
  94. }
  95.  
  96.  
  97.  
  98. };
  99.  
  100. class Button
  101. {
  102. private:
  103. Gpio& pin;
  104. public:
  105. Button(Gpio& pin_in) : pin(pin_in)
  106. {
  107. };
  108.  
  109. void button_pressed()
  110. {
  111. std::cout << "Button pressed" << std::endl;
  112. }
  113.  
  114. void init()
  115. {
  116. pin.enable_irq([this]() { this->button_pressed(); });
  117. }
  118.  
  119.  
  120. };
  121.  
  122. int main() {
  123. Gpio some_pin;
  124. Button b(some_pin);
  125. b.init();
  126.  
  127. some_pin.handler();
  128. return 0;
  129. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Button pressed