fork download
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. const static auto null = nullptr;
  5.  
  6. template<typename TFuncSignature>
  7. class Callback;
  8.  
  9. template<typename R, typename A1>
  10. class Callback<R (A1)> {
  11. public:
  12. typedef R (*TFunc)(void*, A1);
  13.  
  14. Callback() : obj(0), func(0) {}
  15. Callback(void* o, TFunc f) : obj(o), func(f) {}
  16.  
  17. R operator()(A1 a1) const {
  18. return (*func)(obj, a1);
  19. }
  20.  
  21. typedef void* Callback::*SafeBoolType;
  22. operator SafeBoolType () const {
  23. return func != 0? &Callback::obj : 0;
  24. }
  25.  
  26. bool operator! () const {
  27. return func == 0;
  28. }
  29.  
  30. bool operator== ( const Callback<R (A1)>& right ) const {
  31. return obj == right.obj && func == right.func;
  32. }
  33.  
  34. bool operator!= ( const Callback<R (A1)>& right ) const {
  35. return obj != right.obj || func != right.func;
  36. }
  37.  
  38. private:
  39. void* obj;
  40. TFunc func;
  41. };
  42.  
  43. template<typename R, class T, typename A1>
  44. struct DeduceMemCallbackTag {
  45. template<R (T::*Func)(A1)>
  46. static R Wrapper(void* o, A1 a1) {
  47. return (static_cast<T*>(o)->*Func)(a1);
  48. }
  49.  
  50. template<R (T::*Func)(A1)>
  51. inline static Callback<R (A1)> Bind(T* o) {
  52. return Callback<R (A1)>(o, &DeduceMemCallbackTag::Wrapper<Func>);
  53. }
  54. };
  55.  
  56. template<typename R, typename A1>
  57. struct DeduceStaticCallbackTag {
  58. template<R (*Func)(A1)>
  59. static R Wrapper(void*, A1 a1) {
  60. return (*Func)(a1);
  61. }
  62.  
  63. template<R (*Func)(A1)>
  64. inline static Callback<R (A1)> Bind( ) {
  65. return Callback<R (A1)>( 0, &DeduceStaticCallbackTag::Wrapper<Func> );
  66. }
  67. };
  68.  
  69. template<typename R, class T, typename A1>
  70. DeduceMemCallbackTag<R, T, A1> DeduceMemCallback(R (T::*)(A1)) {
  71. return DeduceMemCallbackTag<R, T, A1>();
  72. }
  73.  
  74. template<typename R, typename A1>
  75. DeduceStaticCallbackTag<R, A1> DeduceStaticCallback(R (*)(A1)) {
  76. return DeduceStaticCallbackTag<R, A1>();
  77. }
  78.  
  79. template <typename T1> class Event {
  80. public:
  81. typedef void(* TSignature)( T1 );
  82. typedef Callback<void( T1 )> TCallback;
  83.  
  84. protected:
  85. std::vector<TCallback> invocations;
  86. std::vector<Event<T1>*> events;
  87.  
  88. public:
  89. const static int ExpectedFunctorCount = 2;
  90.  
  91. Event () : invocations(), events() {
  92. invocations.reserve( ExpectedFunctorCount );
  93. events.reserve( ExpectedFunctorCount );
  94. }
  95.  
  96. template <void (* TFunc)(T1)> void Add ( ) {
  97. TCallback c = DeduceStaticCallback( TFunc ).template Bind< TFunc >( );
  98. invocations.push_back( c );
  99. }
  100.  
  101. template <typename T, void (T::* TFunc)(T1)> void Add ( T& object ) {
  102. Add<T, TFunc>( &object );
  103. }
  104.  
  105. template <typename T, void (T::* TFunc)(T1)> void Add ( T* object ) {
  106. TCallback c = DeduceMemCallback( TFunc ).template Bind< TFunc >( object );
  107. invocations.push_back( c );
  108. }
  109.  
  110. void Invoke ( T1 t1 ) {
  111. size_t i;
  112. for ( i = 0; i < invocations.size(); ++i ) {
  113. invocations[i]( t1 );
  114. }
  115. for ( i = 0; i < events.size(); ++i ) {
  116. (*events[i])( t1 );
  117. }
  118. }
  119.  
  120. void operator() ( T1 t1 ) {
  121. Invoke( t1 );
  122. }
  123.  
  124. size_t InvocationCount ( ) {
  125. return events.size( ) + invocations.size( );
  126. }
  127.  
  128. template <void (* TFunc)(T1)> bool Remove ( ) {
  129. TCallback target = DeduceStaticCallback( TFunc ).template Bind< TFunc >( );
  130. for ( size_t i = 0; i < invocations.size(); ++i ) {
  131. TCallback& inv = invocations[i];
  132. if ( target == inv ) {
  133. invocations.erase( invocations.begin() + i );
  134. return true;
  135. }
  136. }
  137. return false;
  138. }
  139.  
  140. template <typename T, void (T::* TFunc)(T1)> bool Remove ( T& object ) {
  141. return Remove<T, TFunc>( &object );
  142. }
  143.  
  144. template <typename T, void (T::* TFunc)(T1)> bool Remove ( T* object ) {
  145. TCallback target = DeduceMemCallback( TFunc ).template Bind< TFunc >( object );
  146. for ( size_t i = 0; i < invocations.size(); ++i ) {
  147. TCallback& inv = invocations[i];
  148. if ( target == inv ) {
  149. invocations.erase( invocations.begin() + i );
  150. return true;
  151. }
  152. }
  153. return false;
  154. }
  155.  
  156. };
  157.  
  158. namespace IntStatic {
  159. void VoidTest () { std::cout << "INTO THE VOID" << std::endl; }
  160. void IntTest (int num) { std::cout << "Got myself a " << num << " !" << std::endl; }
  161. void IntTest2 (int num) { std::cout << "Now _I_ Got myself a " << num << " !" << std::endl; }
  162. }
  163. struct Int {
  164. void Test (int num) { std::cout << num << " on the inside of a class... ?" << std::endl; }
  165. void Test2 (int num) { std::cout << num << " on the inside of a struct, yo !" << std::endl; }
  166. static void Test3(int snum) { std::cout << snum << " on the inside of a class... ?" << std::endl; }
  167. };
  168.  
  169. int main(int argc, char* argv[]) {
  170. Event<int> intev;
  171. Int i;
  172. intev.Add<Int, &Int::Test>(i);
  173. intev.Add<&IntStatic::IntTest>();
  174. intev.Add<&IntStatic::IntTest2>();
  175. //intev.Add( Int::Test3 );
  176. intev(20);
  177. intev.Remove<&IntStatic::IntTest>();
  178. intev.Remove<&IntStatic::IntTest>();
  179. intev.Remove<Int, &Int::Test>(i);
  180. //intev.Remove( Int::Test3 );
  181. //intev.Remove( i, &Int::Test );
  182. intev(20);
  183. return 0;
  184. }
  185.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:4:26: error: 'nullptr' was not declared in this scope
prog.cpp:4:26: error: unable to deduce 'const auto' from '<expression error>'
stdout
Standard output is empty