fork(3) download
  1. #include <unordered_map>
  2. #include <string>
  3. #include <utility>
  4. #include <typeinfo>
  5. #include <stdexcept>
  6. #include <iostream>
  7.  
  8. struct BeliefCondFunc
  9. {
  10. using cb_type = bool(*)();
  11. using map_val = std::pair<cb_type, std::type_info const*>;
  12. static std::unordered_map<std::string, map_val> const FuncMap;
  13.  
  14. static bool Greater(int A, int B)
  15. {
  16. return A > B;
  17. }
  18.  
  19. static bool Between(float A, float B, float C)
  20. {
  21. return A > B && A < C;
  22. }
  23.  
  24. template<typename ...Args>
  25. static map_val make_map_val(bool (*func)(Args...)) {
  26.  
  27. return std::make_pair(reinterpret_cast<cb_type>(func),
  28. &typeid(decltype(func)));
  29. }
  30.  
  31. template<typename ...Args>
  32. static bool call(std::string const& key, Args&&... args){
  33. using prototype = bool(*)(Args...);
  34.  
  35. auto& func_n_typeid = FuncMap.at(key);
  36.  
  37. if (typeid(prototype) != *func_n_typeid.second )
  38. throw std::domain_error("Prototype mismatch");
  39.  
  40. return reinterpret_cast<prototype>(func_n_typeid.first)(std::forward<Args>(args)...);
  41. };
  42. };
  43.  
  44. std::unordered_map<std::string, BeliefCondFunc::map_val> const BeliefCondFunc::FuncMap {
  45. {"Greater", make_map_val(&BeliefCondFunc::Greater) },
  46. {"Between", make_map_val(&BeliefCondFunc::Between) }
  47. };
  48.  
  49. int main() {
  50. BeliefCondFunc::call("Greater", 1, 2);
  51.  
  52. try {
  53. BeliefCondFunc::call("Lesser", 1, 2);
  54. } catch (std::out_of_range&) {
  55. std::cout << "No such function\n";
  56. }
  57.  
  58. try {
  59. BeliefCondFunc::call("Between", 1, 2);
  60. } catch (std::domain_error&) {
  61. std::cout << "Wrong number of arguments\n";
  62. }
  63.  
  64. return 0;
  65. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
No such function
Wrong number of arguments