#include <functional> #include <memory> #include <tuple> #include <vector> #include <type_traits> #include <unordered_map> #include <boost/any.hpp> namespace s { template<typename ... Types> struct signal { using function_type = std::function<void(Types...)>; using tuple_type = std::tuple<Types...>; }; template<typename T> void* type_to_unique_value_helper() { static int dummy = 0; return static_cast<void*>(&dummy); } std::unordered_map<void*, std::vector<boost::any>>& signal_map() { static std::unordered_map<void*, std::vector<boost::any>> m; return m; } template<typename SIGNAL> void bind(typename SIGNAL::function_type f) { signal_map()[type_to_unique_value_helper<SIGNAL>()].emplace_back(f); } template<typename SIGNAL, typename ... Types> void emit(Types ... args) { static_assert( std::is_convertible<std::tuple<Types...>, typename SIGNAL::tuple_type>::value, "args unmatch"); for(auto& f : signal_map()[type_to_unique_value_helper<SIGNAL>()]) { boost::any_cast<typename SIGNAL::function_type>(f)( args ... ); } } }