fork download
  1. #include <boost/optional.hpp>
  2. #include <boost/bind.hpp>
  3. #include <boost/preprocessor/slot/counter.hpp>
  4. #include <iostream>
  5. #include <ostream>
  6. using namespace std;
  7.  
  8. template<unsigned ID,typename Functor>
  9. boost::optional<Functor> &get_local()
  10. {
  11. static boost::optional<Functor> local;
  12. return local;
  13. }
  14.  
  15. template<unsigned ID,typename Functor>
  16. typename Functor::result_type wrapper()
  17. {
  18. return get_local<ID,Functor>().get()();
  19. }
  20.  
  21. template<typename ReturnType>
  22. struct Func
  23. {
  24. typedef ReturnType (*type)();
  25. };
  26.  
  27. template<unsigned ID,typename Functor>
  28. typename Func<typename Functor::result_type>::type get_wrapper(Functor f)
  29. {
  30. (get_local<ID,Functor>()) = f;
  31. return wrapper<ID,Functor>;
  32. }
  33.  
  34. // ----------------------------------------------------------------------
  35.  
  36. void test(void (*fptr)())
  37. {
  38. fptr();
  39. }
  40.  
  41. struct SomeStruct
  42. {
  43. int data;
  44. void some_method()
  45. {
  46. cout << data << endl;
  47. }
  48. void another_method()
  49. {
  50. cout << -data << endl;
  51. }
  52. };
  53.  
  54. int main()
  55. {
  56. SomeStruct local[] = { {11}, {22}, {33} };
  57.  
  58. #include BOOST_PP_UPDATE_COUNTER()
  59. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::some_method,local[0]) ));
  60. #include BOOST_PP_UPDATE_COUNTER()
  61. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::another_method,local[0]) ));
  62.  
  63. #include BOOST_PP_UPDATE_COUNTER()
  64. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::some_method,local[1]) ));
  65. #include BOOST_PP_UPDATE_COUNTER()
  66. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::another_method,local[1]) ));
  67.  
  68. #include BOOST_PP_UPDATE_COUNTER()
  69. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::some_method,local[2]) ));
  70. #include BOOST_PP_UPDATE_COUNTER()
  71. test(get_wrapper<BOOST_PP_COUNTER>( boost::bind(&SomeStruct::another_method,local[2]) ));
  72.  
  73. #include BOOST_PP_UPDATE_COUNTER()
  74. std::cout<<BOOST_PP_COUNTER<<std::endl;
  75. #include BOOST_PP_UPDATE_COUNTER()
  76. std::cout<<BOOST_PP_COUNTER<<std::endl;
  77. #include BOOST_PP_UPDATE_COUNTER()
  78. std::cout<<BOOST_PP_COUNTER<<std::endl;
  79. }
  80.  
Success #stdin #stdout 0.01s 2684KB
stdin
Standard input is empty
stdout
11
-11
22
-22
33
-33
7
8
9