I'm implementing a generic setting reader. The idea is that I have an application which settings can be boolean, integers and strings. Then I have a Config class where the getters for such settings are implemented, the config class takes a customer in the constructor, so that it knows it will read settings for that very customer.
I'm having troubles in having that working, I think I am misusing boost::function confusing it with plain function pointer.
In the maps I'd like to have references while the boost::function
shall be binded only at config read time since there I have allocated a Config
instance for the given customer.
The problem is that I cannot use function pointers without typedefs and this complicates the template work, any wiser solution ?
#include "Config.h"
class ConfigReader
{
ConfigReader();
template<class R>
R readConfig(std::string customer, std::string settingName);
private:
typedef bool (Config::* BoolConfigFunctor) () const;
std::map<std::string, BoolConfigFunctor> boolConfigMap;
typedef int(Config::* IntConfigFunctor) () const;
std::map<std::string, IntConfigFunctor> integerConfigMap;
typedef std::string (Config::* StrConfigFunctor) () const;
std::map<std::string, StrConfigFunctor> stringConfigMap;
template<class R>
std::map<std::string, R (Config::* ) () > getConfigMap();
}
ConfigReader()
{
// INIT all settings you want to be readable in the functor maps
boolConfigMap["USE_NEW_VERSION"] = &Config::useNewVersion;
boolConfigMap["MAINTENANCE_MODE"] = &Config::isMaintenance;
integerConfigMap["TIMEOUT"] = &Config::getTimeout;
stringConfigMap["USERNAME"] = &Config::getUserName;
...
}
template<class R>
R readConfig(std::string customer, std::string settingName)
{
R returnValue;
typedef typename std::map<AMD_STD::string, R (Config::* ) () > ConfigMap_t;
typedef typename ConfigMap_t::const_iterator ConfigMapIter_t;
ConfigMap_t configMap = getConfigMap<R>();
ConfigMapIter_t configIter = configMap.find(settingName);
if (configIter != configMap.end())
{
Config config(customer); // Real instance of Config against which we want to call the function
boost::function<R ()> configFunction;
configFunction =
boost::bind(
configIter->second,
config);
returnValue= configFunction();
}
return returnValue;
}
template<>
std::map<std::string, bool (Config::* ) ()> ConfigReader::getConfigMap()
{
return boolConfigMap;
}
template<>
std::map<std::string, int (Config::* ) ()> ConfigReader::getConfigMap()
{
return integerConfigMap;
}
template<>
std::map<std::string, string (Config::* ) ()> ConfigReader::getConfigMap()
{
return stringConfigMap;
}
UPDATE it did work by using function references in maps rather than boost::function