diff --git a/CepGen/Core/ModuleFactory.h b/CepGen/Core/ModuleFactory.h index 622d57b..5582d78 100644 --- a/CepGen/Core/ModuleFactory.h +++ b/CepGen/Core/ModuleFactory.h @@ -1,99 +1,96 @@ #ifndef CepGen_Core_ModuleFactory_h #define CepGen_Core_ModuleFactory_h #include "CepGen/Core/ParametersList.h" #include #include #include #include #define BUILDERNM( obj ) obj ## Builder #define STRINGIFY( name ) #name namespace cepgen { /// A generic factory to build modules /// \tparam T Base class to build /// \tparam I Indexing variable type template class ModuleFactory { public: /// Retrieve a unique instance of this factory static ModuleFactory& get() { static ModuleFactory instance; return instance; } /// Default destructor ~ModuleFactory() = default; /// Register a named module in the database /// \tparam U Class to register (inherited from T base class) template void registerModule( const I& name, const ParametersList& def_params = ParametersList() ) { - static_assert( std::is_base_of::value, "\n Failed to register an object with improper inheritance into the factory." ); - map_[name] = &create; + static_assert( std::is_base_of::value, "\n\n *** Failed to register an object with improper inheritance into the factory. ***\n" ); + map_[name] = &build; params_map_[name] = def_params; } /// Build one instance of a named module /// \param[in] name Module name to retrieve /// \param[in] params List of parameters to be invoked by the constructor std::unique_ptr build( const I& name, ParametersList params = ParametersList() ) const { if ( name == I() || map_.count( name ) == 0 ) { std::ostringstream oss; - oss << __PRETTY_FUNCTION__ << "\n Failed to retrieve a module with index \"" << name << "\" from factory!"; - throw std::runtime_error( oss.str() ); + oss << __PRETTY_FUNCTION__ << "\n\n *** Failed to build a module with index/name \"" << name << "\" from factory! ***\n"; + throw std::invalid_argument( oss.str() ); } if ( params_map_.count( name ) > 0 ) params += params_map_.at( name ); return map_.at( name )( params ); } /// Build one instance of a named module /// \param[in] params List of parameters to be invoked by the constructor std::unique_ptr build( ParametersList params = ParametersList() ) const { if ( params.has( KEY ) ) { const I& idx = params.get( KEY ); - if ( map_.count( idx ) == 0 ) { - std::ostringstream oss; - oss << __PRETTY_FUNCTION__ << " Failed to retrieve a module with index \"" << idx << "\" from factory!"; - throw std::runtime_error( oss.str() ); - } + if ( map_.count( idx ) == 0 ) + throw std::invalid_argument( std::string( __PRETTY_FUNCTION__ )+"\n\n *** Failed to build a module with index/name \""+std::to_string( idx )+"\" from factory! ***\n" ); if ( params_map_.count( idx ) > 0 ) params += params_map_.at( idx ); return map_.at( idx )( params ); } else - throw std::runtime_error( std::string( __PRETTY_FUNCTION__ )+" Failed to retrieve an indexing key from parameters to build from factory!" ); + throw std::invalid_argument( std::string( __PRETTY_FUNCTION__ )+"\n\n *** Failed to retrieve an indexing key from parameters to build from factory! ***\n" ); } /// List of modules registred in the database std::vector modules() const { std::vector out; for ( const auto& p : map_ ) out.emplace_back( p.first ); return out; } static constexpr const char* KEY = "id"; private: explicit ModuleFactory() = default; /// Construct a module with its parameters set - template static std::unique_ptr create( const ParametersList& params ) { + template static std::unique_ptr build( const ParametersList& params ) { return std::unique_ptr( new U( params ) ); } protected: /// Constructor type for a module typedef std::unique_ptr (*ModCreate)( const ParametersList& ); /// Database of modules handled by this instance std::unordered_map map_; /// Database of default parameters associated to modules std::unordered_map params_map_; public: ModuleFactory( const ModuleFactory& ) = delete; void operator=( const ModuleFactory& ) = delete; }; } #endif