/**
* @brief Implements a simple dispatch mechanism using std::bind
*/
#include <functional>
#include <string>
#include <map>
#include <iostream>
using namespace std::placeholders; // for _1 .. _N
// Our dispatch map, that maps names to functions with a prototype of void(int)
using dispatch_map = std::map<std::string, std::function<void(int)> >;
// A test dispatch function
bool dispatch_function(int testval)
{
// just for testing, return true if > 0, else false
return testval > 0;
}
// Generic dispatch function executor
void executor(std::function<bool(int)> dispfunc, int testval)
{
// pre-condition: testval must NOT be zero!
if (0 == testval)
{
throw std::runtime_error(
"dispatch function error: testval cannot be zero");
}
// execute dispatch function
auto ok = dispfunc(testval);
// post-condition: dispfunc must return true, else error!
if (!ok)
{
throw std::runtime_error(
"dispatch function error: " + std::to_string(testval));
}
// If we get here we've passed all pre and post conditions!
std::cout << "OK: " + std::to_string(testval) << std::endl;
}
// Dispatcher (normally a class but to keep things simple it's a function)
void dispatch(dispatch_map & dispmap, std::string func_name, int testval)
{
try
{
// find the requested function in the map
auto itr_func = dispmap.find(func_name);
// if we didn't find it that's bad..!
if (itr_func == dispmap.end())
{
throw std::runtime_error("unknown dispatch function");
}
// Get a reference to the function we are going to execute
auto & func = itr_func->second;
// execute the function
func(testval);
}
catch(std::exception const & e)
{
// gah, there be dragons!!!
std::cerr << e.what() << std::endl;
}
}
int main()
{
// create a dispatch map
auto && dispmap = dispatch_map
{
// register a dispatch function bound to the executor
{ "my_disp_func", std::bind(executor, dispatch_function, _1) }
};
// fire the dispatcher functions
dispatch(dispmap, "my_disp_func", 1); // will not output an error
dispatch(dispmap, "my_disp_func", 0); // will output an error
dispatch(dispmap, "my_disp_func", -1); // will output an error
}