#include <iostream>
#include <memory>
#include <vector>
#include <functional>
using namespace std;
struct Input {
char c;
string s;
vector<int>v;
};
class Base {
public:
Base(){cout<<"Base ";}
};
class Foo : public Base {
public:
Foo (int) {cout<<"Foo ";}
};
class Bar : public Base {
public:
Bar (string, int) {cout<<"Bar-constructor1 ";}
Bar (string, vector<int>) {cout<<"Bar-constructor2 ";}
};
class MyFactory {
public:
static unique_ptr<Base> createBase(Input& input){
// first that fires, returns the element
for (int i=0; i<test.size(); i++) {
if (test[i](input)) {
cout<<"Rule "<<i<<": ";
return create[i](input);
}
}
// here, either create a Base or, if it's abstract or wrong arguments, throw
cout<<"No rule found: ";
return make_unique<Base>();
}
static void registerDerivate(function<bool(Input&)>t, function<unique_ptr<Base>(Input&)>c){
test.push_back(t);
create.push_back(c);
}
private:
static vector<function<bool(Input&)>> test;
static vector<function<unique_ptr<Base>(Input&)>> create;
};
vector<function<bool(Input&)>> MyFactory::test;
vector<function<unique_ptr<Base>(Input&)>> MyFactory::create;
int main() {
// the "smart" parametric factory is assembled
MyFactory::registerDerivate ([](Input& input){ return input.c=='F' && input.v.size()==1; },
[](Input& input) { return make_unique<Foo>(input.v[0]); } );
MyFactory::registerDerivate ([](Input& input){ return input.c=='B' && input.v.size()==1; },
[](Input& input) { return make_unique<Bar>(input.s, input.v[0]); } );
MyFactory::registerDerivate ([](Input& input){ return input.c=='B' && input.v.size()!=1; },
[](Input& input) { return make_unique<Bar>(input.s, input.v); } );
// your code goes here
Input i1{'X', "no match", {}};
Input i2{'F', "no match", {2,3}};
Input i3{'F', "match Foo", {4}};
Input i4{'B', "match Bar", {5}};
Input i5{'B', "match Bar other constructor", {1,2,3,4}};
auto p1=MyFactory::createBase(i1); cout<<endl;
auto p2=MyFactory::createBase(i2); cout<<endl;
auto p3=MyFactory::createBase(i3); cout<<endl;
auto p4=MyFactory::createBase(i4); cout<<endl;
auto p5=MyFactory::createBase(i5); cout<<endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgSW5wdXQgewoJY2hhciBjOyAKCXN0cmluZyBzOwoJdmVjdG9yPGludD52OyAKfTsKCmNsYXNzIEJhc2UgewpwdWJsaWM6CglCYXNlKCl7Y291dDw8IkJhc2UgIjt9Cn07CmNsYXNzIEZvbyA6IHB1YmxpYyBCYXNlIHsKcHVibGljOiAKCUZvbyAoaW50KSB7Y291dDw8IkZvbyAiO30KfTsKY2xhc3MgQmFyIDogcHVibGljIEJhc2UgewpwdWJsaWM6IAoJQmFyIChzdHJpbmcsIGludCkge2NvdXQ8PCJCYXItY29uc3RydWN0b3IxICI7fQoJQmFyIChzdHJpbmcsIHZlY3RvcjxpbnQ+KSB7Y291dDw8IkJhci1jb25zdHJ1Y3RvcjIgIjt9Cn07CgpjbGFzcyBNeUZhY3RvcnkgewpwdWJsaWM6CiAgIHN0YXRpYyB1bmlxdWVfcHRyPEJhc2U+IGNyZWF0ZUJhc2UoSW5wdXQmIGlucHV0KXsKICAgCSAgICAvLyBmaXJzdCB0aGF0IGZpcmVzLCAgcmV0dXJucyB0aGUgZWxlbWVudAogICAJCWZvciAoaW50IGk9MDsgaTx0ZXN0LnNpemUoKTsgaSsrKSB7CiAgIAkJCWlmICh0ZXN0W2ldKGlucHV0KSkgeyAKICAgCQkJCWNvdXQ8PCJSdWxlICI8PGk8PCI6ICI7CiAgIAkJCQlyZXR1cm4gY3JlYXRlW2ldKGlucHV0KTsKICAgCQkJfQogICAJCX0KICAgCQkvLyBoZXJlLCAgZWl0aGVyIGNyZWF0ZSBhIEJhc2Ugb3IsIGlmIGl0J3MgYWJzdHJhY3Qgb3Igd3JvbmcgYXJndW1lbnRzLCB0aHJvdwogICAJCWNvdXQ8PCJObyBydWxlIGZvdW5kOiAiOwogICAJCXJldHVybiBtYWtlX3VuaXF1ZTxCYXNlPigpOwogICAJCiAgIH0KICAgc3RhdGljIHZvaWQgcmVnaXN0ZXJEZXJpdmF0ZShmdW5jdGlvbjxib29sKElucHV0Jik+dCwgZnVuY3Rpb248dW5pcXVlX3B0cjxCYXNlPihJbnB1dCYpPmMpewogICAJdGVzdC5wdXNoX2JhY2sodCk7CiAgIAljcmVhdGUucHVzaF9iYWNrKGMpOwogICB9CnByaXZhdGU6IAoJc3RhdGljIHZlY3RvcjxmdW5jdGlvbjxib29sKElucHV0Jik+PiB0ZXN0OwoJc3RhdGljIHZlY3RvcjxmdW5jdGlvbjx1bmlxdWVfcHRyPEJhc2U+KElucHV0Jik+PiBjcmVhdGU7Cn07Cgp2ZWN0b3I8ZnVuY3Rpb248Ym9vbChJbnB1dCYpPj4gTXlGYWN0b3J5Ojp0ZXN0Owp2ZWN0b3I8ZnVuY3Rpb248dW5pcXVlX3B0cjxCYXNlPihJbnB1dCYpPj4gTXlGYWN0b3J5OjpjcmVhdGU7CgoKaW50IG1haW4oKSB7CgkvLyB0aGUgInNtYXJ0IiBwYXJhbWV0cmljIGZhY3RvcnkgaXMgYXNzZW1ibGVkCglNeUZhY3Rvcnk6OnJlZ2lzdGVyRGVyaXZhdGUgKFtdKElucHV0JiBpbnB1dCl7IHJldHVybiBpbnB1dC5jPT0nRicgJiYgaW5wdXQudi5zaXplKCk9PTE7IH0sCgkJCQkJCQkJW10oSW5wdXQmIGlucHV0KSB7IHJldHVybiBtYWtlX3VuaXF1ZTxGb28+KGlucHV0LnZbMF0pOyB9ICk7CglNeUZhY3Rvcnk6OnJlZ2lzdGVyRGVyaXZhdGUgKFtdKElucHV0JiBpbnB1dCl7IHJldHVybiBpbnB1dC5jPT0nQicgJiYgaW5wdXQudi5zaXplKCk9PTE7IH0sCgkJCQkJCQkJW10oSW5wdXQmIGlucHV0KSB7IHJldHVybiBtYWtlX3VuaXF1ZTxCYXI+KGlucHV0LnMsIGlucHV0LnZbMF0pOyB9ICk7CglNeUZhY3Rvcnk6OnJlZ2lzdGVyRGVyaXZhdGUgKFtdKElucHV0JiBpbnB1dCl7IHJldHVybiBpbnB1dC5jPT0nQicgJiYgaW5wdXQudi5zaXplKCkhPTE7IH0sCgkJCQkJCQkJW10oSW5wdXQmIGlucHV0KSB7IHJldHVybiBtYWtlX3VuaXF1ZTxCYXI+KGlucHV0LnMsIGlucHV0LnYpOyB9ICk7CgkvLyB5b3VyIGNvZGUgZ29lcyBoZXJlCglJbnB1dCBpMXsnWCcsICJubyBtYXRjaCIsIHt9fTsKCUlucHV0IGkyeydGJywgIm5vIG1hdGNoIiwgezIsM319OyAKCUlucHV0IGkzeydGJywgIm1hdGNoIEZvbyIsIHs0fX07IAoJSW5wdXQgaTR7J0InLCAibWF0Y2ggQmFyIiwgezV9fTsgCglJbnB1dCBpNXsnQicsICJtYXRjaCBCYXIgb3RoZXIgY29uc3RydWN0b3IiLCB7MSwyLDMsNH19OyAKCWF1dG8gcDE9TXlGYWN0b3J5OjpjcmVhdGVCYXNlKGkxKTsgY291dDw8ZW5kbDsgCglhdXRvIHAyPU15RmFjdG9yeTo6Y3JlYXRlQmFzZShpMik7IGNvdXQ8PGVuZGw7IAoJYXV0byBwMz1NeUZhY3Rvcnk6OmNyZWF0ZUJhc2UoaTMpOyBjb3V0PDxlbmRsOyAKCWF1dG8gcDQ9TXlGYWN0b3J5OjpjcmVhdGVCYXNlKGk0KTsgY291dDw8ZW5kbDsgCglhdXRvIHA1PU15RmFjdG9yeTo6Y3JlYXRlQmFzZShpNSk7IGNvdXQ8PGVuZGw7IAoKCXJldHVybiAwOwp9