Skip to content

Instantly share code, notes, and snippets.

@patrislav1
Created November 13, 2022 13:05
Show Gist options
  • Save patrislav1/06b6b5b82aaef34b9c7acb4ba37fb0bd to your computer and use it in GitHub Desktop.
Save patrislav1/06b6b5b82aaef34b9c7acb4ba37fb0bd to your computer and use it in GitHub Desktop.
Simple factory
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <string>
struct Base {
virtual std::string blub() = 0;
};
struct Foo : public Base {
virtual std::string blub() override { return "Foo"; }
};
struct Bar : public Base {
virtual std::string blub() override { return "Bar"; }
};
typedef std::map<std::string, std::function<std::unique_ptr<Base>(void)>>
FactoryTab;
class Factory {
FactoryTab _tab;
public:
Factory(const FactoryTab tab) : _tab{tab} {}
template <typename T> static std::unique_ptr<Base> make() {
static_assert(std::is_base_of_v<Base, T>,
"T must be derived from Base");
return std::make_unique<T>();
}
std::vector<std::string> keys() {
std::vector<std::string> result;
for (auto &kvp : _tab) {
result.emplace_back(kvp.first);
}
return result;
}
std::unique_ptr<Base> create(std::string key) {
auto it = _tab.find(key);
if (it == _tab.end()) {
return nullptr;
}
return it->second();
}
};
int main(void) {
Factory factory{{
{"Foo", Factory::make<Foo>},
{"Bar", Factory::make<Bar>},
}};
std::cout << "supported keys:\n";
for (auto s : factory.keys()) {
std::cout << s << "\n";
}
auto p = factory.create("Bar");
if (!p) {
return 1;
}
std::cout << "blub(): " << p->blub() << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment