#ifndef REFLECTIVE_RAPIDJSON_CODE_FACTORY_H #define REFLECTIVE_RAPIDJSON_CODE_FACTORY_H #include "./codegenerator.h" #include #include #include #include #include namespace clang { class CompilerInstance; } // namespace clang namespace ReflectiveRapidJSON { class Consumer; class Visitor; /*! * \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files. * \remarks * - The code is written to a specified std::ostream instance. * - The CodeFactory class is constituted by its underlying CodeGenerator instances. */ class CodeFactory { friend class Consumer; friend class Visitor; public: CodeFactory( const char *applicationPath, const std::vector &sourceFiles, const std::vector &clangOptions, std::ostream &os); ~CodeFactory(); const std::vector> &generators() const; template void addGenerator(Args &&... args); template auto bindGenerator(Args &&... args); bool run(); clang::CompilerInstance *compilerInstance(); void setCompilerInstance(clang::CompilerInstance *compilerInstance); private: struct ToolInvocation; void addDeclaration(clang::Decl *decl); bool generate() const; std::vector makeClangArgs() const; const char *const m_applicationPath; const std::vector &m_sourceFiles; const std::vector &m_clangOptions; std::ostream &m_os; std::vector> m_generators; std::unique_ptr m_toolInvocation; clang::CompilerInstance *m_compilerInstance; }; template void CodeFactory::addGenerator(Args &&... args) { 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; } inline clang::CompilerInstance *CodeFactory::compilerInstance() { return m_compilerInstance; } inline void CodeFactory::setCompilerInstance(clang::CompilerInstance *compilerInstance) { m_compilerInstance = compilerInstance; } } // namespace ReflectiveRapidJSON #endif // REFLECTIVE_RAPIDJSON_CODE_FACTORY_H