fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <vector>
  4. #include <functional>
  5.  
  6. using namespace std;
  7.  
  8. struct Input {
  9. char c;
  10. string s;
  11. vector<int>v;
  12. };
  13.  
  14. class Base {
  15. public:
  16. Base(){cout<<"Base ";}
  17. };
  18. class Foo : public Base {
  19. public:
  20. Foo (int) {cout<<"Foo ";}
  21. };
  22. class Bar : public Base {
  23. public:
  24. Bar (string, int) {cout<<"Bar-constructor1 ";}
  25. Bar (string, vector<int>) {cout<<"Bar-constructor2 ";}
  26. };
  27.  
  28. class MyFactory {
  29. public:
  30. static unique_ptr<Base> createBase(Input& input){
  31. // first that fires, returns the element
  32. for (int i=0; i<test.size(); i++) {
  33. if (test[i](input)) {
  34. cout<<"Rule "<<i<<": ";
  35. return create[i](input);
  36. }
  37. }
  38. // here, either create a Base or, if it's abstract or wrong arguments, throw
  39. cout<<"No rule found: ";
  40. return make_unique<Base>();
  41.  
  42. }
  43. static void registerDerivate(function<bool(Input&)>t, function<unique_ptr<Base>(Input&)>c){
  44. test.push_back(t);
  45. create.push_back(c);
  46. }
  47. private:
  48. static vector<function<bool(Input&)>> test;
  49. static vector<function<unique_ptr<Base>(Input&)>> create;
  50. };
  51.  
  52. vector<function<bool(Input&)>> MyFactory::test;
  53. vector<function<unique_ptr<Base>(Input&)>> MyFactory::create;
  54.  
  55.  
  56. int main() {
  57. // the "smart" parametric factory is assembled
  58. MyFactory::registerDerivate ([](Input& input){ return input.c=='F' && input.v.size()==1; },
  59. [](Input& input) { return make_unique<Foo>(input.v[0]); } );
  60. MyFactory::registerDerivate ([](Input& input){ return input.c=='B' && input.v.size()==1; },
  61. [](Input& input) { return make_unique<Bar>(input.s, input.v[0]); } );
  62. MyFactory::registerDerivate ([](Input& input){ return input.c=='B' && input.v.size()!=1; },
  63. [](Input& input) { return make_unique<Bar>(input.s, input.v); } );
  64. // your code goes here
  65. Input i1{'X', "no match", {}};
  66. Input i2{'F', "no match", {2,3}};
  67. Input i3{'F', "match Foo", {4}};
  68. Input i4{'B', "match Bar", {5}};
  69. Input i5{'B', "match Bar other constructor", {1,2,3,4}};
  70. auto p1=MyFactory::createBase(i1); cout<<endl;
  71. auto p2=MyFactory::createBase(i2); cout<<endl;
  72. auto p3=MyFactory::createBase(i3); cout<<endl;
  73. auto p4=MyFactory::createBase(i4); cout<<endl;
  74. auto p5=MyFactory::createBase(i5); cout<<endl;
  75.  
  76. return 0;
  77. }
Success #stdin #stdout 0s 5292KB
stdin
Standard input is empty
stdout
No rule found: Base 
No rule found: Base 
Rule 0: Base Foo 
Rule 1: Base Bar-constructor1 
Rule 2: Base Bar-constructor2