#include #include #include #include #include #include #include // // https://github.com/qicosmos/cosmos/blob/master/function_traits.hpp // https://codechina.gitcode.host/programmer/2016/145-programmer-2016.html // https://zhuanlan.zhihu.com/p/33330839 // // //转换为std::function和函数指针. template struct function_traits; //普通函数. template struct function_traits { public: enum { arity = sizeof...(Args) }; typedef Ret function_type(Args...); typedef Ret return_type; using stl_function_type = std::function; typedef Ret (*pointer)(Args...); template struct args { static_assert(I < arity, "index is out of range, index must less than sizeof Args"); using type = typename std::tuple_element>::type; }; typedef std::tuple>...> tuple_type; typedef std::tuple>...> bare_tuple_type; }; //函数指针. template struct function_traits : function_traits { }; //std::function. template struct function_traits> : function_traits { }; //member function. #define FUNCTION_TRAITS(...) template struct function_traits : function_traits { }; FUNCTION_TRAITS() FUNCTION_TRAITS(const) FUNCTION_TRAITS(volatile) FUNCTION_TRAITS(const volatile) //函数对象. template struct function_traits : function_traits { }; template typename function_traits::stl_function_type to_function(const Function &lambda) { return static_cast::stl_function_type>(lambda); } template typename function_traits::stl_function_type to_function(Function &&lambda) { return static_cast::stl_function_type>(std::forward(lambda)); } template typename function_traits::pointer to_function_pointer(const Function &lambda) { return static_cast::pointer>(lambda); } // =============================================== template struct seq { using type = seq; }; template struct concat; template struct concat, seq> : public seq { }; template struct make : public concat, typename make::type> { }; template <> struct make<1> : public seq<0> { }; template <> struct make<0> : public seq<> { }; // ================================================ class FunctionContainer { std::map> invokers_; public: template class invoker { public: static inline void apply(const func &f, void *args) { using tuple_type = typename function_traits::tuple_type; const tuple_type *tp = static_cast(args); forward_call(f, *tp); } }; template void register_handler(const std::string &name, const Func &f) { using std::placeholders::_1; invokers_[name] = {std::bind(&invoker::apply, f, _1)}; } template void call(const std::string &name, Args &&...args) { auto item = invokers_.find(name); if (item == invokers_.end()) { return; } auto args_tuple = std::make_tuple(std::forward(args)...); char data[sizeof(std::tuple)]; std::tuple *tp = new (data) std::tuple; *tp = args_tuple; item->second(tp); } template static void forward_call(const F &f, const std::tuple &tp) { call_helper(f, make{}, tp); } template static decltype(auto) call_helper(const F &f, const seq &, const std::tuple &tp) { return f(std::get(tp)...); } }; int main() { FunctionContainer fc; auto g = [&](int a, int b) { std::cout << a << " " << b << std::endl; }; auto countup = [&](int stop) { int x = 0; while (x < stop) { std::cout << "up: " << x << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); x++; } }; fc.register_handler>("g", g); fc.register_handler>("countup", countup); fc.call("g", 3, 6); fc.call("countup", 5); }
V2
#include #include #include #include #include #include #include #include #include #include #include // // https://github.com/qicosmos/cosmos/blob/master/function_traits.hpp // https://codechina.gitcode.host/programmer/2016/145-programmer-2016.html // https://zhuanlan.zhihu.com/p/33330839 // // //转换为std::function和函数指针. template struct function_traits; //普通函数. template struct function_traits { public: enum { arity = sizeof...(Args) }; typedef Ret function_type(Args...); typedef Ret return_type; using stl_function_type = std::function; typedef Ret (*pointer)(Args...); template struct args { static_assert(I < arity, "index is out of range, index must less than sizeof Args"); using type = typename std::tuple_element>::type; }; typedef std::tuple>...> tuple_type; typedef std::tuple>...> bare_tuple_type; }; //函数指针. template struct function_traits : function_traits { }; //std::function. template struct function_traits> : function_traits { }; //member function. #define FUNCTION_TRAITS(...) template struct function_traits : function_traits { }; FUNCTION_TRAITS() FUNCTION_TRAITS(const) FUNCTION_TRAITS(volatile) FUNCTION_TRAITS(const volatile) //函数对象. template struct function_traits : function_traits { }; template typename function_traits::stl_function_type to_function(const Function &lambda) { return static_cast::stl_function_type>(lambda); } template typename function_traits::stl_function_type to_function(Function &&lambda) { return static_cast::stl_function_type>(std::forward(lambda)); } template typename function_traits::pointer to_function_pointer(const Function &lambda) { return static_cast::pointer>(lambda); } // =============================================== template struct seq { using type = seq; }; template struct concat; template struct concat, seq> : public seq { }; template struct make : public concat, typename make::type> { }; template <> struct make<1> : public seq<0> { }; template <> struct make<0> : public seq<> { }; // ================================================ class FunctionContainer { using TimePoint = std::chrono::high_resolution_clock::time_point; using BindFunc = std::function; using SleepingTask = std::tuple; class TaskCompare { public: TaskCompare() {} bool operator()(const SleepingTask &a, const SleepingTask &b) { return std::get<0>(a) >= std::get<0>(b); } }; private: std::priority_queue, TaskCompare> sleeping_; std::map> invokers_; std::deque> readys_; template class invoker { public: static inline void apply(const func &f, void *args) { using tuple_type = typename function_traits::tuple_type; const tuple_type *tp = static_cast(args); forward_call(f, *tp); } template static inline void apply2(const func &f, std::tuple args) { using tuple_type = typename function_traits::tuple_type; // const tuple_type *tp = static_cast(args); forward_call(f, args); } }; public: template void register_handler(const std::string &name, const Func &f) { using std::placeholders::_1; invokers_[name] = {std::bind(&invoker::apply, f, _1)}; } // template void call_soon( const Func &f, Args... args) { using std::placeholders::_1; auto args_tuple = std::make_tuple(std::forward(args)...); char data[sizeof(std::tuple)]; std::tuple *tp = new (data) std::tuple; *tp = args_tuple; readys_.push_back(std::bind(&invoker::template apply2, f, *tp)); // ↑↑↑↑↑↑ 这个template的添加太TM坑了!!!↑↑↑↑↑↑ // https://segmentfault.com/q/1010000021553693 // https://github.com/eliasdaler/metaStuff/issues/12 } template void call_later(int seconds, const Func &f, Args... args) { using std::placeholders::_1; auto args_tuple = std::make_tuple(std::forward(args)...); TimePoint deadline = std::chrono::high_resolution_clock::now() + std::chrono::seconds(seconds); sleeping_.push(std::make_tuple(deadline, std::bind(&invoker::template apply2, f, args_tuple))); } void run() { while (!readys_.empty() || !sleeping_.empty()) { if (readys_.empty()) { auto top = sleeping_.top(); sleeping_.pop(); ; if (std::get<0>(top) > std::chrono::high_resolution_clock::now()) { std::this_thread::sleep_for(std::get<0>(top) - std::chrono::high_resolution_clock::now()); } readys_.push_back(std::get<1>(top)); } auto f = readys_.front(); readys_.pop_front(); f(); } } // private: template void call(const std::string &name, Args &&...args) { auto item = invokers_.find(name); if (item == invokers_.end()) { return; } auto args_tuple = std::make_tuple(std::forward(args)...); char data[sizeof(std::tuple)]; std::tuple *tp = new (data) std::tuple; *tp = args_tuple; item->second(tp); } private: template static void forward_call(const F &f, const std::tuple &tp) { call_helper(f, make{}, tp); } template static decltype(auto) call_helper(const F &f, const seq &, const std::tuple &tp) { return f(std::get(tp)...); } }; void sum(int a, int b, int *ret) { *ret = a + b; } int main() { FunctionContainer fc; auto g = [&](int a, int b) { std::cout << a << " " << b << std::endl; }; std::function countdown; countdown = [&](int s) { if (s > 0) { std::cout << "down: " << s << std::endl; // std::this_thread::sleep_for(std::chrono::seconds(1)); // fc.call_soon(countdown, s - 1); fc.call_later(4, countdown, s - 1); } }; std::function countup; countup = [&](int stop, int x_) { int x = x_; if (x < stop) { std::cout << "up: " << x << std::endl; // std::this_thread::sleep_for(std::chrono::seconds(1)); // fc.call_soon(countup, stop, x + 1); fc.call_later(4, countup, stop, x + 1); } }; // std::function s = sum; // fc.register_handler>("g", g); // fc.register_handler>("countup", countup); // fc.register_handler>("sum", s); // fc.call("g", 3, 6); // fc.call("countup", 5); // int r; // fc.call("sum", 3, 6, &r); // std::cout << r << std::endl; fc.call_soon>(countdown, 6); fc.call_soon>(countup, 6, 0); fc.run(); }
上一篇 centos编译mqtt
下一篇 k8s部署pod
版权所有 (c)2021-2022 MSHXW.COM
ICP备案号:晋ICP备2021003244-6号