Created
November 2, 2016 15:01
-
-
Save Psirus/300e56e6de820a350eda89a239cb0204 to your computer and use it in GitHub Desktop.
Design problem for programmers SE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <map> | |
#include <boost/any.hpp> | |
enum class eInput { | |
ONE, TWO, THREE | |
}; | |
// are a string, a double and an int | |
enum class eOutput { | |
SPAM, HAM, EGGS | |
}; | |
// are a string, a double and an int | |
using InputMap = std::map<eInput, boost::any>; | |
using OutputMap = std::map<eOutput, boost::any>; | |
class PluginBase | |
{ | |
public: | |
virtual void Evaluate(InputMap& inputs, OutputMap& outputs) = 0; | |
virtual InputMap GetInputs(OutputMap& outputs) = 0; | |
}; | |
class PluginA : public PluginBase | |
{ | |
public: | |
void Evaluate(InputMap& inputs, OutputMap& outputs) override | |
{ | |
for(auto& out : outputs) | |
{ | |
switch(out.first) | |
{ | |
case eOutput::SPAM: | |
out.second = "Hello " | |
+ boost::any_cast<std::string>(inputs.at(eInput::ONE)) | |
+ std::to_string(boost::any_cast<int>(inputs.at(eInput::THREE))); | |
break; | |
default: | |
throw std::runtime_error("This Plugin can't handle anything besides SPAM"); | |
} | |
} | |
} | |
InputMap GetInputs(OutputMap& outputs) override | |
{ | |
InputMap inputs; | |
for (auto& out : outputs) | |
{ | |
switch(out.first) | |
{ | |
case eOutput::SPAM: | |
inputs[eInput::ONE]; | |
inputs[eInput::THREE]; | |
break; | |
default: | |
throw std::runtime_error("This Plugin can't handle anything besides SPAM"); | |
} | |
} | |
return inputs; | |
} | |
}; | |
class PluginB : public PluginBase | |
{ | |
public: | |
void Evaluate(InputMap& inputs, OutputMap& outputs) override | |
{ | |
for(auto& out : outputs) | |
{ | |
switch(out.first) | |
{ | |
case eOutput::HAM: | |
out.second = 2.0*boost::any_cast<double>(inputs.at(eInput::TWO)); | |
break; | |
case eOutput::EGGS: | |
out.second = 4 + boost::any_cast<int>(inputs.at(eInput::THREE)); | |
break; | |
default: | |
throw std::runtime_error("This Plugin can't handle anything besides HAM & EGGS"); | |
} | |
} | |
} | |
InputMap GetInputs(OutputMap& outputs) override | |
{ | |
InputMap inputs; | |
for (auto& out : outputs) | |
{ | |
switch(out.first) | |
{ | |
case eOutput::HAM: | |
inputs[eInput::TWO]; | |
break; | |
case eOutput::EGGS: | |
inputs[eInput::THREE]; | |
break; | |
default: | |
throw std::runtime_error("This Plugin can't handle anything besides HAM & EGGS"); | |
} | |
} | |
return inputs; | |
} | |
}; | |
class Handler | |
{ | |
public: | |
Handler(PluginBase* rPlugin) : plugin(rPlugin) {} | |
void ShowOutputs(OutputMap& outputs) | |
{ | |
InputMap inputs = plugin->GetInputs(outputs); | |
for (auto& in : inputs) | |
{ | |
switch(in.first) | |
{ | |
case eInput::ONE: | |
in.second = std::string("World"); | |
break; | |
case eInput::TWO: | |
in.second = 43.0; | |
break; | |
case eInput::THREE: | |
in.second = 5; | |
break; | |
default: | |
throw std::runtime_error("Can't handle this input."); | |
} | |
} | |
plugin->Evaluate(inputs, outputs); | |
for (auto& out : outputs) | |
{ | |
switch(out.first) | |
{ | |
case eOutput::SPAM: | |
std::cout << boost::any_cast<std::string>(out.second) << std::endl; | |
break; | |
case eOutput::HAM: | |
std::cout << boost::any_cast<double>(out.second) << std::endl; | |
break; | |
case eOutput::EGGS: | |
std::cout << boost::any_cast<int>(out.second) << std::endl; | |
break; | |
default: | |
throw std::runtime_error("Can't show this output."); | |
} | |
} | |
} | |
private: | |
PluginBase* plugin; | |
}; | |
int main() | |
{ | |
PluginA pluginA; | |
Handler handler(&pluginA); | |
OutputMap outputs; | |
outputs[eOutput::SPAM]; | |
handler.ShowOutputs(outputs); | |
PluginB pluginB; | |
Handler handler2(&pluginB); | |
OutputMap outputs2; | |
outputs2[eOutput::HAM]; | |
handler2.ShowOutputs(outputs2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment