I know the title is not meaningful, couldn't find anything better.
I need to provide a C++ interface to an SQlite table, where I can store key/value/type configuration settings, such as
Key | Value | Type
PATH | /path/to/ | STRING
HAS_FEATURE | Y | BOOLEAN
REFRESH_RATE| 60 | INTEGER
For simplicity and flexibility purposes the datamodel hosts the values as strings but provides a column to retain the original data type.
This is how I have imagined a client to call such c++ interface.
Configuration c;
int refreshRate = c.get<int>("REFRESH_RATE");
// Next line throws since type won't match
std::string refreshRate = c.get<std::string>("REFRESH_RATE");
This is how I have imagined implementing it (I know the code won't compile as is, consider it as pseudo c++, I'm more questioning the design than the syntax here)
class Parameter
{
public:
enum KnownTypes
{
STRING = 0,
BOOLEAN,
INTEGER,
DOUBLE,
...
}
std::string key;
std::string value;
KnownTypes type;
}
class Configuration
{
public:
template<class RETURNTYPE>
RETURNTYPE get(std::string& key)
{
// get parameter(eg. get cached value or from db...)
const Parameter& parameter = retrieveFromDbOrCache(key);
return <parameter.type, RETURNTYPE>getImpl(parameter);
}
private:
template<int ENUMTYPE, class RETURNTYPE>
RETURNTYPE getImpl(const Parameter& parameter)
{
throw "Tthe requested return type does not match with the actual parameter's type"; // shall never happen
}
template<Parameter::KnownTypes::STRING, std::string>
std::string getImpl(const Parameter& parameter)
{
return parameter.value;
}
template<Parameter::KnownTypes::BOOLEAN, bool>
std::string getImpl(const Parameter& parameter)
{
return parameter.value == "Y";
}
template<Parameter::KnownTypes::INTEGER, int>
int getImpl(const Parameter& parameter)
{
return lexical_cast<int>(parameter.value)
}
// and so on, specialize once per known type
};
Is that a good implementation ? Any suggestions on how to improve it ?
I know I could have specialized the public get
directly per return type, but I would have duplicated some code in each template specialization (the type consistency check as well as the parameter retrieval)