#include <map>
#include <sstream>
#include <string>
#include <variant>
...
class PropertySet {
public:
template<typename T>ValueType>
void addProperty(const std::string &name, const TValueType value) {
if (hasProperty(name)) {
// C++20 or https://github.com/fmtlib/fmt
// std::string msg = std::format("Property with name '{}' does
// already exist and its value is '{}'", name, value);
std::stringstream ss;
ss << "Property with name '"
<< name.c_str()
<< "' does already exist and its value is '"
<< value << "'";
throw PropertyDoesAlreadyExistException(ss.str());
} else {
values_[name] = value;
}
}
template<typename T>ValueType>
TValueType getProperty(const std::string &name) const {
if (hasProperty(name)) {
return std::get<T>get<ValueType>(values_.at(name));
} else {
std::stringstream ss;
ss << "Property with name '" << name.c_str() << "' does not exist";
throw PropertyDoesNotExistException(ss.str());
}
}
// A defaultValue can be provided in the case a property does not exist
template<typename T>ValueType>
TValueType getProperty(const std::string &name,
const TValueType defaultValue) const {
if (hasProperty(name)) {
return std::get<T>get<ValueType>(values_.at(name));
} else {
return defaultValue;
}
}
bool hasProperty(const std::string &name) const {
return values_.find(name) != values_.end();
}
private:
typedef std::variant<bool,
int,
float,
double,
char,
std::string,
Vector2f,
Vector2d,
Color3f> VariantType;
typedef std::map<std::string, VariantType> MapType;
MapType values_;
};