fork download
  1. #include <boost/shared_ptr.hpp>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <typeinfo>
  5. #include <ostream>
  6. #include <vector>
  7.  
  8. using namespace std;
  9. using namespace boost;
  10.  
  11. typedef int KeyEvent;
  12. typedef void (*func_type)(const KeyEvent &);
  13.  
  14. struct AbstractCallback
  15. {
  16. virtual void operator()(const KeyEvent &p)=0;
  17. virtual bool compare_to(const std::type_info &rhs_type,const void *rhs) const=0;
  18. virtual bool compare_to(const std::type_info &rhs_type,const func_type *rhs) const=0;
  19. virtual bool equals(const AbstractCallback &rhs) const=0;
  20. };
  21.  
  22. template<typename Callback>
  23. struct ConcreteCallback : AbstractCallback
  24. {
  25. Callback callback;
  26. ConcreteCallback(Callback p_callback) : callback(p_callback) {}
  27. void operator()(const KeyEvent &p)
  28. {
  29. callback(p);
  30. }
  31. bool compare_to(const std::type_info &rhs_type,const void *rhs) const
  32. {
  33. return (typeid(Callback)==rhs_type) &&
  34. ( *static_cast<const Callback*>(rhs) == callback );
  35. }
  36. bool compare_to(const std::type_info &rhs_type,const func_type *rhs) const
  37. {
  38. return false;
  39. }
  40. bool equals(const AbstractCallback &rhs) const
  41. {
  42. return rhs.compare_to(typeid(Callback),&callback);
  43. }
  44. };
  45.  
  46. template<>
  47. struct ConcreteCallback<func_type> : AbstractCallback
  48. {
  49. func_type callback;
  50. ConcreteCallback(func_type p_callback) : callback(p_callback) {}
  51. void operator()(const KeyEvent &p)
  52. {
  53. callback(p);
  54. }
  55. bool compare_to(const std::type_info &rhs_type,const void *rhs) const
  56. {
  57. return false;
  58. }
  59. bool compare_to(const std::type_info &rhs_type,const func_type *rhs) const
  60. {
  61. return *rhs == callback;
  62. }
  63. bool equals(const AbstractCallback &rhs) const
  64. {
  65. return rhs.compare_to(typeid(func_type),&callback);
  66. }
  67. };
  68.  
  69.  
  70. struct KeyCallback
  71. {
  72. shared_ptr<AbstractCallback> func;
  73. public:
  74. template<typename Func>
  75. KeyCallback(Func f) : func(new ConcreteCallback<Func>(f)) {}
  76. friend bool operator==(const KeyCallback &lhs,const KeyCallback &rhs)
  77. {
  78. return lhs.func->equals(*rhs.func);
  79. }
  80. void operator()(const KeyEvent &p)
  81. {
  82. (*func)(p);
  83. }
  84. };
  85.  
  86. void func1(const KeyEvent &)
  87. {
  88. cout << "func1" << endl;
  89. }
  90.  
  91. void func3(const KeyEvent &)
  92. {
  93. cout << "func3" << endl;
  94. }
  95.  
  96. class func2
  97. {
  98. int data;
  99. public:
  100. func2(int n) : data(n) {}
  101. friend bool operator==(const func2 &lhs,const func2 &rhs)
  102. {
  103. return lhs.data==rhs.data;
  104. }
  105. void operator()(const KeyEvent &)
  106. {
  107. cout << "func2, data=" << data << endl;
  108. }
  109. };
  110.  
  111. struct Caller
  112. {
  113. template<typename F>
  114. void operator()(F f)
  115. {
  116. f(1);
  117. }
  118. };
  119.  
  120. int main(int argc,char *argv[])
  121. {
  122. vector<KeyCallback> v;
  123.  
  124. v.push_back(KeyCallback(func1));
  125. v.push_back(KeyCallback(func1));
  126. v.push_back(KeyCallback(func1));
  127.  
  128. v.push_back(KeyCallback(func2(1)));
  129. v.push_back(KeyCallback(func2(1)));
  130.  
  131. v.push_back(KeyCallback(func2(2)));
  132. v.push_back(KeyCallback(func2(2)));
  133. v.push_back(KeyCallback(func2(2)));
  134. v.push_back(KeyCallback(func2(2)));
  135.  
  136. v.push_back(KeyCallback(func3));
  137.  
  138. for_each(v.begin(),v.end(),Caller());
  139.  
  140. cout << count(v.begin(),v.end(),KeyCallback(func1)) << endl;
  141. cout << count(v.begin(),v.end(),KeyCallback(func2(1))) << endl;
  142. cout << count(v.begin(),v.end(),KeyCallback(func2(2))) << endl;
  143. cout << count(v.begin(),v.end(),KeyCallback(func3)) << endl;
  144. return 0;
  145. }
Success #stdin #stdout 0.01s 2868KB
stdin
Standard input is empty
stdout
func1
func1
func1
func2, data=1
func2, data=1
func2, data=2
func2, data=2
func2, data=2
func2, data=2
func3
3
2
4
1