Advertisement
Guest User

Untitled

a guest
Jun 25th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.78 KB | None | 0 0
  1.  
  2. #include <string>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <unordered_map>
  6. #include <type_traits>
  7. #include <tuple>
  8. #include <utility>
  9.  
  10. using namespace std;
  11.  
  12. void hello()
  13. {
  14. }
  15.  
  16. void pri(int i)
  17. {
  18.     cout << i << "\n";
  19. }
  20.  
  21. void prif(int i, float f)
  22. {
  23.     cout << i << " " << f << "\n";
  24. }
  25.  
  26. void prs(const string& s)
  27. {
  28.     cout << s << "\n";
  29. }
  30.  
  31. struct printer
  32. {
  33.     void h(const string& s)
  34.     {
  35.         cout << "printer[" << this << "]: " << s << "\n";
  36.     }
  37.     void hellobj(const char* s, int i)
  38.     {
  39.         cout << "s=" << s << ", i=" << i << "\n";
  40.     }
  41. };
  42.  
  43. struct IFunction
  44. {
  45.     virtual void Call(void* obj, stringstream& argSS) = 0;
  46. };
  47.  
  48.  
  49. template<class T> struct TempArgType { using type = T; };
  50. template<class T> struct TempArgType<T&> { using type = typename TempArgType<T>::type; };
  51. template<class T> struct TempArgType<const T&> { using type = typename TempArgType<T>::type; };
  52. template<> struct TempArgType<const char*>
  53. {
  54.     struct type
  55.     {
  56.         operator const char* () const { return data.c_str(); }
  57.  
  58.         std::string data;
  59.     };
  60. };
  61. istream& operator >> (istream& src, TempArgType<const char*>::type& me)
  62. {
  63.     src >> me.data;
  64. }
  65.  
  66.  
  67. template<size_t> struct int_{};
  68.  
  69. template <class Tuple, size_t Pos>
  70. istream& ReadTuple(istream& src, Tuple& t, int_<Pos>)
  71. {
  72.     src >> get<tuple_size<Tuple>::value - Pos>(t);
  73.     return ReadTuple(src, t, int_<Pos - 1>());
  74. }
  75.  
  76. template <class Tuple>
  77. istream& ReadTuple(istream& src, Tuple& t, int_<0>) {}
  78.  
  79.  
  80. // implementation details, users never invoke these directly
  81. namespace detail
  82. {
  83.     template <typename F, typename Tuple, bool Done, int Total, int... N>
  84.     struct call_impl
  85.     {
  86.         static void call(F f, Tuple && t)
  87.         {
  88.             call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t));
  89.         }
  90.     };
  91.  
  92.     template <typename F, typename Tuple, int Total, int... N>
  93.     struct call_impl<F, Tuple, true, Total, N...>
  94.     {
  95.         static void call(F f, Tuple && t)
  96.         {
  97.             f(std::get<N>(std::forward<Tuple>(t))...);
  98.         }
  99.     };
  100.  
  101.     template <typename OT, typename F, typename Tuple, bool Done, int Total, int... N>
  102.     struct callm_impl
  103.     {
  104.         static void call(OT* o, F f, Tuple && t)
  105.         {
  106.             callm_impl<OT, F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(o, f, std::forward<Tuple>(t));
  107.         }
  108.     };
  109.  
  110.     template <typename OT, typename F, typename Tuple, int Total, int... N>
  111.     struct callm_impl<OT, F, Tuple, true, Total, N...>
  112.     {
  113.         static void call(OT* o, F f, Tuple && t)
  114.         {
  115.             (o->*f)(std::get<N>(std::forward<Tuple>(t))...);
  116.         }
  117.     };
  118. }
  119.  
  120. // user invokes this
  121. template <typename F, typename Tuple>
  122. void call(F f, Tuple && t)
  123. {
  124.     typedef typename std::decay<Tuple>::type ttype;
  125.     detail::call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
  126. }
  127. template <typename OT, typename F, typename Tuple>
  128. void callm(OT* o, F f, Tuple && t)
  129. {
  130.     typedef typename std::decay<Tuple>::type ttype;
  131.     detail::callm_impl<OT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(o, f, std::forward<Tuple>(t));
  132. }
  133.  
  134.  
  135. template<class RT, class... ArgTypes>
  136. struct Function : IFunction
  137. {
  138.     Function(RT (*f)(ArgTypes...)) : func(f) {}
  139.     void Call(void* /* obj */, stringstream& argSS) override
  140.     {
  141.         tuple<typename TempArgType<ArgTypes>::type...> argInsts;
  142.         ReadTuple(argSS, argInsts, int_<sizeof...(ArgTypes)>());
  143.         call(func, argInsts);
  144.     }
  145.     RT (*func)(ArgTypes...);
  146. };
  147.  
  148. template<class RT, class... ArgTypes>
  149. IFunction* CreateFunction(RT (*f)(ArgTypes...))
  150. {
  151.     return new Function<RT, ArgTypes...>(f);
  152. }
  153.  
  154.  
  155. template<class OT, class RT, class... ArgTypes>
  156. struct Method : IFunction
  157. {
  158.     Method(RT (OT::*f)(ArgTypes...)) : func(f) {}
  159.     void Call(void* obj, stringstream& argSS) override
  160.     {
  161.         tuple<typename TempArgType<ArgTypes>::type...> argInsts;
  162.         ReadTuple(argSS, argInsts, int_<sizeof...(ArgTypes)>());
  163.         callm(static_cast<OT*>(obj), func, argInsts);
  164.     }
  165.     RT (OT::*func)(ArgTypes...);
  166. };
  167.  
  168. template<class OT, class RT, class... ArgTypes>
  169. IFunction* CreateFunction(RT (OT::*f)(ArgTypes...))
  170. {
  171.     return new Method<OT, RT, ArgTypes...>(f);
  172. }
  173.  
  174.  
  175. unordered_map<string, IFunction*> g_funcs =
  176. {
  177.     { "hello", CreateFunction(hello) },
  178.     { "pri", CreateFunction(pri) },
  179.     { "prif", CreateFunction(prif) },
  180.     { "prs", CreateFunction(prs) },
  181.     { "printer:h", CreateFunction(printer::h) },
  182.     { "printer:hellobj", CreateFunction(printer::hellobj) },
  183. };
  184.  
  185. int main()
  186. {
  187.     printer p;
  188.     while (!cin.eof())
  189.     {
  190.         // read command
  191.         string cmd;
  192.         getline(cin, cmd);
  193.         stringstream ss(cmd);
  194.        
  195.         // parse command
  196.         string fn;
  197.         ss >> fn;
  198.         auto fnit = g_funcs.find(fn);
  199.         if (fnit == g_funcs.end())
  200.         {
  201.             cerr << "> could not find function: '" << fn << "'\n";
  202.             continue;
  203.         }
  204.         cerr << "> called '" << fn << "'\n";
  205.         fnit->second->Call(&p, ss);
  206.     }
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement