Use hash map to find specified code generator
So adding further generators will not result in having a lot of "else if (!strcmp(..." conditions. This also allows to improve the error message.
This commit is contained in:
parent
1eaa2d52c2
commit
0d2f39a2b5
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "./codegenerator.h"
|
#include "./codegenerator.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -34,6 +35,7 @@ public:
|
||||||
|
|
||||||
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
||||||
template <typename GeneratorType, typename... Args> void addGenerator(Args &&... args);
|
template <typename GeneratorType, typename... Args> void addGenerator(Args &&... args);
|
||||||
|
template <typename GeneratorType, typename... Args> auto bindGenerator(Args &&... args);
|
||||||
|
|
||||||
bool run();
|
bool run();
|
||||||
clang::CompilerInstance *compilerInstance();
|
clang::CompilerInstance *compilerInstance();
|
||||||
|
@ -60,6 +62,28 @@ template <typename GeneratorType, typename... Args> void CodeFactory::addGenerat
|
||||||
m_generators.emplace_back(std::make_unique<GeneratorType>(*this, std::forward<Args>(args)...));
|
m_generators.emplace_back(std::make_unique<GeneratorType>(*this, std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Detail {
|
||||||
|
template <typename T> std::reference_wrapper<const T> wrapReferences(const T &val)
|
||||||
|
{
|
||||||
|
return std::cref(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> std::reference_wrapper<T> wrapReferences(T &val)
|
||||||
|
{
|
||||||
|
return std::ref(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T &&wrapReferences(T &&val)
|
||||||
|
{
|
||||||
|
return std::forward<T>(val);
|
||||||
|
}
|
||||||
|
} // namespace Detail
|
||||||
|
|
||||||
|
template <typename GeneratorType, typename... Args> auto CodeFactory::bindGenerator(Args &&... args)
|
||||||
|
{
|
||||||
|
return std::bind(&CodeFactory::addGenerator<GeneratorType, Args...>, this, Detail::wrapReferences(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
||||||
{
|
{
|
||||||
return m_generators;
|
return m_generators;
|
||||||
|
|
|
@ -15,6 +15,7 @@ class JsonSerializationCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
struct Options {
|
struct Options {
|
||||||
Options();
|
Options();
|
||||||
|
Options(const Options &other) = delete;
|
||||||
void appendTo(ApplicationUtilities::Argument *arg);
|
void appendTo(ApplicationUtilities::Argument *arg);
|
||||||
|
|
||||||
ApplicationUtilities::ConfigValueArgument additionalClassesArg;
|
ApplicationUtilities::ConfigValueArgument additionalClassesArg;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ApplicationUtilities;
|
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);
|
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()) {
|
if (generatorsArg.isPresent()) {
|
||||||
|
// define mapping of generator names to generator constructions (add new generators here!)
|
||||||
|
// clang-format off
|
||||||
|
const std::unordered_map<std::string, std::function<void()>> generatorsByName{
|
||||||
|
{ "json", factory.bindGenerator<JsonSerializationCodeGenerator, const JsonSerializationCodeGenerator::Options &>(jsonOptions) }
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
// find and construct generators by name
|
// find and construct generators by name
|
||||||
for (const char *generatorName : generatorsArg.values(0)) {
|
for (const char *generatorName : generatorsArg.values(0)) {
|
||||||
if (!strcmp(generatorName, "json")) {
|
try {
|
||||||
factory.addGenerator<JsonSerializationCodeGenerator>(jsonOptions);
|
generatorsByName.at(generatorName)();
|
||||||
} else {
|
} catch (const out_of_range &) {
|
||||||
cerr << Phrases::Error << "The specified generator \"" << generatorName << "\" does not exist." << Phrases::EndFlush;
|
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;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue