fork(11) download
  1. // Copyright Evgeny Panasyuk 2012.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://w...content-available-to-author-only...t.org/LICENSE_1_0.txt)
  5.  
  6. #include <type_traits>
  7. #include <functional>
  8. #include <algorithm>
  9. #include <stdexcept>
  10. #include <iostream>
  11. #include <typeinfo>
  12. #include <utility>
  13. #include <ostream>
  14. #include <vector>
  15. #include <string>
  16.  
  17. using namespace std;
  18.  
  19. // _____________________________Implementation__________________________________________
  20.  
  21. #define USE_VARIADIC_TEMPLATES 0
  22.  
  23. template<typename Callback,typename Function> inline
  24. bool func_compare(const Function &lhs,const Function &rhs)
  25. {
  26. typedef typename conditional
  27. <
  28. is_function<Callback>::value,
  29. typename add_pointer<Callback>::type,
  30. Callback
  31. >::type request_type;
  32.  
  33. if (const request_type *lhs_internal = lhs.template target<request_type>())
  34. if (const request_type *rhs_internal = rhs.template target<request_type>())
  35. return *rhs_internal == *lhs_internal;
  36. return false;
  37. }
  38.  
  39. #if USE_VARIADIC_TEMPLATES
  40. #define FUNC_SIG_TYPES typename ...Args
  41. #define FUNC_SIG_TYPES_PASS Args...
  42. #else
  43. #define FUNC_SIG_TYPES typename function_signature
  44. #define FUNC_SIG_TYPES_PASS function_signature
  45. #endif
  46.  
  47. template<FUNC_SIG_TYPES>
  48. struct function_comparable: function<FUNC_SIG_TYPES_PASS>
  49. {
  50. typedef function<FUNC_SIG_TYPES_PASS> Function;
  51. bool (*type_holder)(const Function &,const Function &);
  52. public:
  53. function_comparable() {}
  54. template<typename Func> function_comparable(Func f)
  55. : Function(f), type_holder(func_compare<Func,Function>)
  56. {
  57. }
  58. template<typename Func> function_comparable &operator=(Func f)
  59. {
  60. Function::operator=(f);
  61. type_holder=func_compare<Func,Function>;
  62. return *this;
  63. }
  64. friend bool operator==(const Function &lhs,const function_comparable &rhs)
  65. {
  66. return rhs.type_holder(lhs,rhs);
  67. }
  68. friend bool operator==(const function_comparable &lhs,const Function &rhs)
  69. {
  70. return rhs==lhs;
  71. }
  72. // ...
  73. friend void swap(function_comparable &lhs,function_comparable &rhs)// noexcept
  74. {
  75. lhs.swap(rhs);
  76. lhs.type_holder.swap(rhs.type_holder);
  77. }
  78. };
  79.  
  80. // ________________________________Example______________________________________________
  81.  
  82. typedef void (function_signature)();
  83.  
  84. void func1()
  85. {
  86. cout << "func1" << endl;
  87. }
  88.  
  89. void func3()
  90. {
  91. cout << "func3" << endl;
  92. }
  93.  
  94. class func2
  95. {
  96. int data;
  97. public:
  98. explicit func2(int n) : data(n) {}
  99. friend bool operator==(const func2 &lhs,const func2 &rhs)
  100. {
  101. return lhs.data==rhs.data;
  102. }
  103. void operator()()
  104. {
  105. cout << "func2, data=" << data << endl;
  106. }
  107. };
  108. struct Caller
  109. {
  110. template<typename Func>
  111. void operator()(Func f)
  112. {
  113. f();
  114. }
  115. };
  116. class Callbacks
  117. {
  118. vector<function<function_signature>> v;
  119. public:
  120. void register_callback_comparator(function_comparable<function_signature> callback)
  121. {
  122. v.push_back(callback);
  123. }
  124. void register_callback(function<function_signature> callback)
  125. {
  126. v.push_back(callback);
  127. }
  128. void unregister_callback(function_comparable<function_signature> callback)
  129. {
  130. auto it=find(v.begin(),v.end(),callback);
  131. if(it!=v.end())
  132. v.erase(it);
  133. else
  134. throw runtime_error("not found");
  135. }
  136. void call_all()
  137. {
  138. for_each(v.begin(),v.end(),Caller());
  139. cout << string(16,'_') << endl;
  140. }
  141. };
  142.  
  143. int main()
  144. {
  145. Callbacks cb;
  146. function_comparable<function_signature> f;
  147. f=func1;
  148. cb.register_callback_comparator(f);
  149.  
  150. cb.register_callback(func2(1));
  151. cb.register_callback(func2(2));
  152. cb.register_callback(func3);
  153. cb.call_all();
  154.  
  155. cb.unregister_callback(func2(2));
  156. cb.call_all();
  157. cb.unregister_callback(func1);
  158. cb.call_all();
  159. }
  160.  
Success #stdin #stdout 0s 3024KB
stdin
Standard input is empty
stdout
func1
func2, data=1
func2, data=2
func3
________________
func1
func2, data=1
func3
________________
func2, data=1
func3
________________