#ifndef __CONFIG_CONFIGURATION_H__ #define __CONFIG_CONFIGURATION_H__ /* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include #include #include #include "Poco/Any.h" #include "Poco/Exception.h" #include "Poco/Format.h" namespace Util { /* ******************************************************************************* * CLASS DECLARE ******************************************************************************* */ class Configuration { private: class Parameter { public: template T getValue() { return Poco::AnyCast(_value); } void setValue(const Poco::Any& value) { this->_value = value; } void setChanged(bool changed) { this->_changed = changed; } bool getChanged() { return _changed; } bool empty() { return _value.empty(); } Poco::Any& value() { return _value; } private: Poco::Any _value; bool _changed; }; public: class ParameterNames: public std::unordered_set { public: bool exists(std::string name) const; }; public: virtual ~Configuration(); template Configuration& setParameter(const std::string& name, const T& value) { Parameter& parameter = _parameters[name]; if (parameter.empty() || parameter.getValue() != value) { parameter.setChanged(true); parameter.setValue(value); } return *this; } template T getParameter(const std::string& name) { return findParameter(name).getValue(); } bool isParameterChanged(const std::string& name) { return findParameter(name).getChanged(); } void confirmParameterChanged(const std::string& name) { findParameter(name).setChanged(false); } void getChangedParameters(ParameterNames& names) { names.clear(); for (auto& p : _parameters) { if (p.second.getChanged()) names.insert(p.first); } } const std::string& name() const { return _name; } void copyTo(Configuration& other); protected: void setName(std::string& name) { _name = name; } Parameter& findParameter(const std::string& name) { if (_parameters.find(name) == _parameters.end()) throw Poco::NotFoundException(Poco::format("Can't find parameter: %s", name), -ENODATA); return _parameters[name]; } private: using Parameters = std::map; Parameters _parameters; std::string _name; }; } #endif