/* fuzzylite (R), a fuzzy logic control library in C++. Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. Author: Juan Rada-Vilela, Ph.D. This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under the terms of the FuzzyLite License included with the software. You should have received a copy of the FuzzyLite License along with fuzzylite. If not, see . fuzzylite is a registered trademark of FuzzyLite Limited. */ #ifndef FL_CONSTRUCTIONFACTORY_H #define FL_CONSTRUCTIONFACTORY_H #include "fl/fuzzylite.h" #include #include #include namespace fl { /** The ConstructionFactory class is the base class for a factory whose objects are created from a registered ConstructionFactory::Constructor. @author Juan Rada-Vilela, Ph.D. @see FactoryManager @since 5.0 */ template class ConstructionFactory { public: /** The Constructor type definition refers to a zero-parameter method which returns an instance of T */ typedef T(*Constructor)(); private: std::string _name; std::map _constructors; public: explicit ConstructionFactory(const std::string& name); virtual ~ConstructionFactory(); FL_DEFAULT_COPY_AND_MOVE(ConstructionFactory) /** Returns the name of the factory @return the name of the factory */ virtual std::string name() const; /** Registers the constructor in the factory @param key is the unique name by which constructors are registered @param constructor is the pointer to the constructor of the object */ virtual void registerConstructor(const std::string& key, Constructor constructor); /** Deregisters from the factory the constructor associated to the given key @param key is the unique name by which constructors are registered */ virtual void deregisterConstructor(const std::string& key); /** Checks whether the factory has a constructor registered by the given key @param key is the unique name by which constructors are registered @return whether the factory has the given constructor registered */ virtual bool hasConstructor(const std::string& key) const; /** Gets the constructor registered by the given key @param key is the unique name by which constructors are registered @return the pointer to the given constructor */ virtual Constructor getConstructor(const std::string& key) const; /** Creates an object by executing the constructor associated to the given key @param key is the unique name by which constructors are registered @return an object by executing the constructor associated to the given key */ virtual T constructObject(const std::string& key) const; /** Returns a vector of keys for the constructors available @return a vector of keys for the constructors available */ virtual std::vector available() const; /** Gets the map of registered keys and constructors @return the map of registered keys and constructors */ virtual std::map& constructors(); /** Gets an immutable map of registered keys and constructors @return an immutable map of registered keys and constructors */ virtual const std::map& constructors() const; }; } /** * Template implementation */ #include "fl/Exception.h" #include "fl/defuzzifier/Defuzzifier.h" #include "fl/hedge/Hedge.h" #include "fl/norm/SNorm.h" #include "fl/norm/TNorm.h" #include "fl/term/Term.h" namespace fl { template inline ConstructionFactory::ConstructionFactory(const std::string& name) : _name(name) { } template inline ConstructionFactory::~ConstructionFactory() { } template inline std::string ConstructionFactory::name() const { return this->_name; } template inline void ConstructionFactory::registerConstructor(const std::string& key, Constructor constructor) { this->_constructors[key] = constructor; } template inline void ConstructionFactory::deregisterConstructor(const std::string& key) { typename std::map::iterator it = this->_constructors.find(key); if (it != this->_constructors.end()) { this->_constructors.erase(it); } } template inline bool ConstructionFactory::hasConstructor(const std::string& key) const { typename std::map::const_iterator it = this->_constructors.find(key); return (it != this->_constructors.end()); } template inline typename ConstructionFactory::Constructor ConstructionFactory::getConstructor(const std::string& key) const { typename std::map::const_iterator it = this->_constructors.find(key); if (it != this->_constructors.end()) { return it->second; } return fl::null; } template inline T ConstructionFactory::constructObject(const std::string& key) const { typename std::map::const_iterator it = this->_constructors.find(key); if (it != this->_constructors.end()) { if (it->second) { return it->second(); } return fl::null; } std::ostringstream ss; ss << "[factory error] constructor of " + _name + " <" << key << "> not registered"; throw Exception(ss.str(), FL_AT); } template inline std::vector ConstructionFactory::available() const { std::vector result; typename std::map::const_iterator it = this->_constructors.begin(); while (it != this->_constructors.end()) { result.push_back(it->first); ++it; } return result; } template inline std::map::Constructor>& ConstructionFactory::constructors() { return this->_constructors; } template inline const std::map::Constructor>& ConstructionFactory::constructors() const { return this->_constructors; } } #endif /* FL_CONSTRUCTIONFACTORY_H */