Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <iostream>
- #include <sstream>
- #include <unordered_map>
- #include <type_traits>
- #include <tuple>
- #include <utility>
- using namespace std;
- void hello()
- {
- }
- void pri(int i)
- {
- cout << i << "\n";
- }
- void prif(int i, float f)
- {
- cout << i << " " << f << "\n";
- }
- void prs(const string& s)
- {
- cout << s << "\n";
- }
- struct printer
- {
- void h(const string& s)
- {
- cout << "printer[" << this << "]: " << s << "\n";
- }
- void hellobj(const char* s, int i)
- {
- cout << "s=" << s << ", i=" << i << "\n";
- }
- };
- struct IFunction
- {
- virtual void Call(void* obj, stringstream& argSS) = 0;
- };
- template<class T> struct TempArgType { using type = T; };
- template<class T> struct TempArgType<T&> { using type = typename TempArgType<T>::type; };
- template<class T> struct TempArgType<const T&> { using type = typename TempArgType<T>::type; };
- template<> struct TempArgType<const char*>
- {
- struct type
- {
- operator const char* () const { return data.c_str(); }
- std::string data;
- };
- };
- istream& operator >> (istream& src, TempArgType<const char*>::type& me)
- {
- src >> me.data;
- }
- template<size_t> struct int_{};
- template <class Tuple, size_t Pos>
- istream& ReadTuple(istream& src, Tuple& t, int_<Pos>)
- {
- src >> get<tuple_size<Tuple>::value - Pos>(t);
- return ReadTuple(src, t, int_<Pos - 1>());
- }
- template <class Tuple>
- istream& ReadTuple(istream& src, Tuple& t, int_<0>) {}
- // implementation details, users never invoke these directly
- namespace detail
- {
- template <typename F, typename Tuple, bool Done, int Total, int... N>
- struct call_impl
- {
- static void call(F f, Tuple && t)
- {
- call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t));
- }
- };
- template <typename F, typename Tuple, int Total, int... N>
- struct call_impl<F, Tuple, true, Total, N...>
- {
- static void call(F f, Tuple && t)
- {
- f(std::get<N>(std::forward<Tuple>(t))...);
- }
- };
- template <typename OT, typename F, typename Tuple, bool Done, int Total, int... N>
- struct callm_impl
- {
- static void call(OT* o, F f, Tuple && t)
- {
- callm_impl<OT, F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(o, f, std::forward<Tuple>(t));
- }
- };
- template <typename OT, typename F, typename Tuple, int Total, int... N>
- struct callm_impl<OT, F, Tuple, true, Total, N...>
- {
- static void call(OT* o, F f, Tuple && t)
- {
- (o->*f)(std::get<N>(std::forward<Tuple>(t))...);
- }
- };
- }
- // user invokes this
- template <typename F, typename Tuple>
- void call(F f, Tuple && t)
- {
- typedef typename std::decay<Tuple>::type ttype;
- detail::call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
- }
- template <typename OT, typename F, typename Tuple>
- void callm(OT* o, F f, Tuple && t)
- {
- typedef typename std::decay<Tuple>::type ttype;
- detail::callm_impl<OT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(o, f, std::forward<Tuple>(t));
- }
- template<class RT, class... ArgTypes>
- struct Function : IFunction
- {
- Function(RT (*f)(ArgTypes...)) : func(f) {}
- void Call(void* /* obj */, stringstream& argSS) override
- {
- tuple<typename TempArgType<ArgTypes>::type...> argInsts;
- ReadTuple(argSS, argInsts, int_<sizeof...(ArgTypes)>());
- call(func, argInsts);
- }
- RT (*func)(ArgTypes...);
- };
- template<class RT, class... ArgTypes>
- IFunction* CreateFunction(RT (*f)(ArgTypes...))
- {
- return new Function<RT, ArgTypes...>(f);
- }
- template<class OT, class RT, class... ArgTypes>
- struct Method : IFunction
- {
- Method(RT (OT::*f)(ArgTypes...)) : func(f) {}
- void Call(void* obj, stringstream& argSS) override
- {
- tuple<typename TempArgType<ArgTypes>::type...> argInsts;
- ReadTuple(argSS, argInsts, int_<sizeof...(ArgTypes)>());
- callm(static_cast<OT*>(obj), func, argInsts);
- }
- RT (OT::*func)(ArgTypes...);
- };
- template<class OT, class RT, class... ArgTypes>
- IFunction* CreateFunction(RT (OT::*f)(ArgTypes...))
- {
- return new Method<OT, RT, ArgTypes...>(f);
- }
- unordered_map<string, IFunction*> g_funcs =
- {
- { "hello", CreateFunction(hello) },
- { "pri", CreateFunction(pri) },
- { "prif", CreateFunction(prif) },
- { "prs", CreateFunction(prs) },
- { "printer:h", CreateFunction(printer::h) },
- { "printer:hellobj", CreateFunction(printer::hellobj) },
- };
- int main()
- {
- printer p;
- while (!cin.eof())
- {
- // read command
- string cmd;
- getline(cin, cmd);
- stringstream ss(cmd);
- // parse command
- string fn;
- ss >> fn;
- auto fnit = g_funcs.find(fn);
- if (fnit == g_funcs.end())
- {
- cerr << "> could not find function: '" << fn << "'\n";
- continue;
- }
- cerr << "> called '" << fn << "'\n";
- fnit->second->Call(&p, ss);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement