diff --git a/generator/codefactory.h b/generator/codefactory.h index d21e31b..16521e4 100644 --- a/generator/codefactory.h +++ b/generator/codefactory.h @@ -3,6 +3,7 @@ #include "./codegenerator.h" +#include #include #include #include @@ -34,6 +35,7 @@ public: const std::vector> &generators() const; template void addGenerator(Args &&... args); + template auto bindGenerator(Args &&... args); bool run(); clang::CompilerInstance *compilerInstance(); @@ -60,6 +62,28 @@ template void CodeFactory::addGenerat m_generators.emplace_back(std::make_unique(*this, std::forward(args)...)); } +namespace Detail { +template std::reference_wrapper wrapReferences(const T &val) +{ + return std::cref(val); +} + +template std::reference_wrapper wrapReferences(T &val) +{ + return std::ref(val); +} + +template T &&wrapReferences(T &&val) +{ + return std::forward(val); +} +} // namespace Detail + +template auto CodeFactory::bindGenerator(Args &&... args) +{ + return std::bind(&CodeFactory::addGenerator, this, Detail::wrapReferences(std::forward(args)...)); +} + inline const std::vector> &CodeFactory::generators() const { return m_generators; diff --git a/generator/jsonserializationcodegenerator.h b/generator/jsonserializationcodegenerator.h index bf0ee89..f3cecfc 100644 --- a/generator/jsonserializationcodegenerator.h +++ b/generator/jsonserializationcodegenerator.h @@ -15,6 +15,7 @@ class JsonSerializationCodeGenerator : public CodeGenerator { public: struct Options { Options(); + Options(const Options &other) = delete; void appendTo(ApplicationUtilities::Argument *arg); ApplicationUtilities::ConfigValueArgument additionalClassesArg; diff --git a/generator/main.cpp b/generator/main.cpp index c470387..b1dbdcd 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace std; using namespace ApplicationUtilities; @@ -80,16 +81,28 @@ int main(int argc, char *argv[]) } } - // configure code generator + // instantiate the code factory and add generators to it CodeFactory factory(parser.executable(), inputFileArg.values(0), clangOptions, *os); - // add only specified generators if the --generator argument is present + // add specified generators if the --generator argument is present; otherwise add default generators if (generatorsArg.isPresent()) { + // define mapping of generator names to generator constructions (add new generators here!) + // clang-format off + const std::unordered_map> generatorsByName{ + { "json", factory.bindGenerator(jsonOptions) } + }; + // clang-format on + // find and construct generators by name for (const char *generatorName : generatorsArg.values(0)) { - if (!strcmp(generatorName, "json")) { - factory.addGenerator(jsonOptions); - } else { - cerr << Phrases::Error << "The specified generator \"" << generatorName << "\" does not exist." << Phrases::EndFlush; + try { + generatorsByName.at(generatorName)(); + } catch (const out_of_range &) { + cerr << Phrases::Error << "The specified generator \"" << generatorName << "\" does not exist." << Phrases::End; + cerr << "Available generators:"; + for (const auto &generators : generatorsByName) { + cerr << ' ' << generators.first; + } + cerr << endl; return -5; } }