Search Results
ModuleRegistry.h
/*
* MoMEMta: a modular implementation of the Matrix Element Method
* Copyright (C) 2017 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 <mutex>
#include <functional>
#include <momemta/ModuleFactory.h>
#include <momemta/ModuleDefBuilder.h>
namespace momemta {
class ModuleRegistryInterface {
public:
virtual ~ModuleRegistryInterface();
virtual const ModuleRegistrationData& find(const std::string& module_name) const = 0;
};
class ModuleRegistry: ModuleRegistryInterface {
public:
typedef std::function<ModuleRegistrationData()> RegisterOp;
ModuleRegistry();
virtual ~ModuleRegistry() {}
static ModuleRegistry& get();
void registerModule(RegisterOp registration_op);
void deregisterModule(const std::string& module_name);
const ModuleRegistrationData& find(const std::string& module_name) const override;
void exportList(bool ignore_internal, ModuleList& list) const;
void processRegistrations();
private:
void callDeferred() const;
void registerModuleWithLock(RegisterOp registration_op) const;
mutable std::mutex mutex_;
mutable std::vector<RegisterOp> deferred_; // Guarded by mutex_
mutable std::unordered_map<std::string, const ModuleRegistrationData> registry_; // Guarded by mutex_
mutable bool initialized_ = false; // Guarded by mutex_
// Exceptions
class module_already_exists_error: public std::runtime_error {
using std::runtime_error::runtime_error;
};
class module_not_found_error: public std::runtime_error {
using std::runtime_error::runtime_error;
};
};
namespace registration {
struct ModuleDefBuilderReceiver {
// To call ModuleRegistry::get()->register(...), used by the
// REGISTER_MODULE macro below.
// Note: These are implicitly converting constructors.
ModuleDefBuilderReceiver(const ModuleDefBuilder& builder);
~ModuleDefBuilderReceiver();
std::string name_;
};
}
#define REGISTER_MODULE(type) \
REGISTER_MODULE_UNIQ_HELPER(__LINE__, #type, type)
#define REGISTER_MODULE_NAME(name, type) \
REGISTER_MODULE_UNIQ_HELPER(__LINE__, name, type)
#define REGISTER_MODULE_UNIQ_HELPER(ctr, name, type) REGISTER_MODULE_UNIQ(ctr, name, type)
#define REGISTER_MODULE_UNIQ(ctr, name, type) \
static const ::momemta::ModuleFactory::PMaker<type> register_module_factory##ctr(name); \
static const ::momemta::registration::ModuleDefBuilderReceiver register_module##ctr = \
::momemta::registration::ModuleDefBuilder(name).Type<type>()
}