Loading [MathJax]/extensions/tex2jax.js

Search Results

 /*
  *  MoMEMta: a modular implementation of the Matrix Element Method
  *  Copyright (C) 2016  Universite catholique de Louvain (UCL), Belgium
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 
 #pragma once
 
 #include <memory>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
 #include <momemta/Logging.h>
 
 // Plugin system
 template<typename T> class PluginFactory;
 
 template<typename Interface, typename... Args>
 class PluginFactory<Interface* (Args...)> {
     public:
         using type = Interface* (Args...);
         using Factory = PluginFactory<Interface*(Args...)>;
 
         struct PMakerBase {
             virtual std::shared_ptr<Interface> create(Args...) const = 0;
             virtual ~PMakerBase() {}
         };
 
         template<class PluginType>
             struct PMaker: public PMakerBase {
                 PMaker(const std::string& name) {
                     Factory::get().registerPMaker(this, name);
                 }
 
                 virtual std::shared_ptr<Interface> create(Args... args) const override {
                     return std::shared_ptr<PluginType>(new PluginType(std::forward<Args>(args)...));
                 }
             };
 
         std::shared_ptr<Interface> create(const std::string& name, Args... args) const {
             return find(name)->create(std::forward<Args>(args)...);
         }
 
         static PluginFactory<Interface* (Args...)>& get();
 
         void registerPMaker(PMakerBase* pMaker, const std::string& name) {
             auto it = m_plugins.find(name);
             if (it != m_plugins.end())
                 throw plugin_already_exists_error("The plugin type '" + name + "' is already registered in the factory.");
 
             m_plugins.emplace(name, pMaker);
         }
 
         PMakerBase* find(const std::string& name) const {
             auto it = m_plugins.find(name);
             if (it == m_plugins.end()) {
                 LOG(fatal) << "No such plugin type '" << name << "' registered in the factory (" << m_plugins.size() <<" plugins).";
                 throw plugin_not_found_error("No such plugin type '" + name + "' registered in the factory.");
             }
 
             return it->second;
         }
 
         std::vector<std::string> getPluginsList() const {
             std::vector<std::string> result;
             for (const auto& plugin: m_plugins) {
                 result.push_back(plugin.first);
             }
 
             return result;
         }
 
     private:
         class plugin_already_exists_error: public std::runtime_error {
             using std::runtime_error::runtime_error;
         };
 
         class plugin_not_found_error: public std::runtime_error {
             using std::runtime_error::runtime_error;
         };
 
         PluginFactory() = default;
 
         PluginFactory(const PluginFactory&) = delete; // stop default
         const PluginFactory& operator=(const PluginFactory&) = delete; // stop default
 
         std::unordered_map<std::string, PMakerBase*> m_plugins;
 };
 
 #define PLUGIN_UNIQUE_NAME2(x, y) x ## y
 #define PLUGIN_UNIQUE_NAME(x, y) PLUGIN_UNIQUE_NAME2(x, y)
All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Modules Pages