Program Listing for File Configured.hpp¶
↰ Return to documentation for file (src/include/Configured.hpp)
#ifndef SRC_INCLUDE_CONFIGURED_HPP
#define SRC_INCLUDE_CONFIGURED_HPP
#include "Configurator.hpp"
#include <boost/program_options.hpp>
#include <map>
#include <string>
#include <typeinfo>
namespace Nextsim {
class ConfiguredBase {
public:
virtual ~ConfiguredBase() = default;
virtual void configure() = 0;
};
template <typename C> class Configured : public ConfiguredBase {
public:
Configured() = default;
virtual ~Configured() = default;
virtual void configure() = 0;
template <typename T> static void tryConfigure(T& ref);
template <typename T> static void tryConfigure(T* ptr);
template <typename T>
static inline T getConfiguration(const std::string& name, const T& defaultValue)
{
boost::program_options::options_description opt;
addOption(name, defaultValue, opt);
return retrieveValue<T>(name, opt);
}
static void clearConfigurationMap() { singleOptions.clear(); }
static const std::map<int, std::string> keyMap;
protected:
template <typename T> void addOption(const std::string& name, const T& defaultValue)
{
addOption(name, defaultValue, singleOptions[name]);
}
template <typename T> T retrieveValue(const std::string& name)
{
return retrieveValue<T>(name, singleOptions.at(name));
}
private:
template <typename T>
static void addOption(const std::string& name, const T& defaultValue,
boost::program_options::options_description& opt)
{
opt.add_options()(
name.c_str(), boost::program_options::value<T>()->default_value(defaultValue), "");
}
template <typename T>
static T retrieveValue(
const std::string& name, boost::program_options::options_description& opt)
{
return Configurator::parse(opt)[name].as<T>();
}
static std::map<std::string, boost::program_options::options_description> singleOptions;
};
template <typename C>
std::map<std::string, boost::program_options::options_description> Configured<C>::singleOptions;
template <typename C> template <typename T> void Configured<C>::tryConfigure(T& ref)
{
try {
dynamic_cast<ConfiguredBase&>(ref).configure();
} catch (const std::bad_cast& bc) {
// Do nothing. If the reference is not a derived class of Configured, ignore it.
}
}
template <typename C> template <typename T> void Configured<C>::tryConfigure(T* ptr)
{
ConfiguredBase* cfg = dynamic_cast<ConfiguredBase*>(ptr);
if (cfg)
cfg->configure();
}
template <typename T> void tryConfigure(T* p_t) { Configured<int>::tryConfigure(p_t); }
template <typename T> void tryConfigure(T& t) { Configured<int>::tryConfigure(t); }
}
#endif /* SRC_INCLUDE_CONFIGURED_HPP */