5 #ifndef ROADRUNNER_SETTING_H
6 #define ROADRUNNER_SETTING_H
13 #include <type_traits>
16 #include "setting_t.h"
17 #include "rrException.h"
86 explicit Setting(setting_t value);
99 value_(setting_t(settingValue)) {};
109 Setting(
const char *settingValue);
116 explicit Setting(std::int64_t settingValue);
164 return std::holds_alternative<T>(value_);
185 return std::get_if<T>(&value_);
196 template<
class SettingType>
198 return std::get<SettingType>(value_);
214 const std::type_info &inf =
typeInfo();
215 return visit([&](
auto &&val) {
216 if constexpr (std::is_convertible_v<decltype(val), As>) {
217 std::ostringstream os;
218 os <<
"Cannot retrieve setting value: you have requested the value as a ";
219 os <<
"\"" <<
typeid(As).name() <<
"\", but the value of the setting is ";
220 std::ostringstream oss_val;
223 bool isNegInt =
false;
224 uint64_t uint64val = 0;
225 int64_t int64val = 0;
226 if (
auto intValue = std::get_if<int>(&value_))
231 int64val = *intValue;
233 uint64val = *intValue;
234 oss_val <<
"\"" << *intValue <<
"\", which is ";
236 else if (
auto intValue = std::get_if<int64_t>(&value_))
241 int64val = *intValue;
243 oss_val <<
"\"" << *intValue <<
"\", which is ";
244 uint64val = *intValue;
246 else if (
auto intValue = std::get_if<unsigned int>(&value_))
248 oss_val <<
"\"" << *intValue <<
"\", which is ";
249 uint64val = *intValue;
251 else if (
auto intValue = std::get_if<uint64_t>(&value_))
253 oss_val <<
"\"" << *intValue <<
"\", which is ";
254 uint64val = *intValue;
259 if (
typeid(As) ==
typeid(
unsigned int) ||
typeid(As) ==
typeid(
unsigned long)) {
262 os << oss_val.str() <<
"negative." << std::endl;
263 throw std::invalid_argument(os.str());
269 if (
auto lValue = std::get_if<float>(&value_)) {
270 if (*lValue > ((std::numeric_limits<float>::max)())) {
271 os <<
"\"" << *lValue <<
"\", which is too large." << std::endl;
272 throw std::invalid_argument(os.str());
277 if (
typeid(As) ==
typeid(
int) &&
278 (uint64val > ((std::int64_t)(std::numeric_limits<int>::max)()) && !isNegInt) ||
279 (isNegInt && int64val < ((std::int64_t)(std::numeric_limits<int>::min)())))
281 os << oss_val.str() <<
"too large." << std::endl;
282 throw std::invalid_argument(os.str());
285 else if (
typeid(As) ==
typeid(
unsigned int) &&
286 uint64val > ((std::int64_t)(std::numeric_limits<unsigned int>::max)()))
288 os << oss_val.str() <<
"too large." << std::endl;
289 throw std::invalid_argument(os.str());
292 else if (
typeid(As) ==
typeid(int64_t) &&
293 (uint64val > ((std::int64_t)(std::numeric_limits<int64_t>::max)()) && !isNegInt))
295 os << oss_val.str() <<
"too large." << std::endl;
296 throw std::invalid_argument(os.str());
301 std::ostringstream os;
302 os <<
"Setting::getAs:TypeError. You have requested the conversion "
303 "of a \"" <<
typeid(decltype(val)).name() <<
"\" to a ";
304 os <<
"\"" <<
typeid(As).name() <<
"\" but this Setting contains ";
305 os <<
"a \"" << inf.name() <<
"\". Note, see Setting::toString() "
306 "for string representation." << std::endl;
309 throw std::invalid_argument(os.str());
320 template<
class SettingType>
322 return std::get<SettingType>(value_);
345 [&](
auto const &val) {
346 if constexpr (std::is_convertible_v<decltype(val), T>) {
351 throw std::bad_variant_access{};
369 operator std::vector<double>() {
370 if (
auto vec =
get_if<std::vector<double>>()) {
373 throw std::invalid_argument(
"Setting::operator std::vector<double>: "
374 "could not cast Setting to double vector because the "
375 "type contained in this Setting is not a double vector");
399 template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>
::type>
400 bool operator==(
const T &otherSetting) {
401 if (
auto settingValue = get_if<T>()) {
402 return *settingValue == otherSetting;
412 class =
typename std::enable_if<isValidVariantType<T, setting_t>::value>
::type>
413 bool operator!=(
const T &setting) {
414 return !(*
this == setting);
421 bool operator==(
const Setting &setting);
430 bool operator==(
const char *setting);
439 bool operator!=(
const char *setting);
445 bool operator!=(
const Setting &setting);
453 template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>
::type>
457 value_ = setting_t(setting);
466 template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>
::type>
470 value_ = std::move(setting_t(setting));
490 decltype(
auto)
visit(Func function)
const {
491 return std::visit(
function, value_);
499 const std::type_info &
typeInfo()
const;
531 [[nodiscard]]
const setting_t &
getValue()
const;
542 [[nodiscard]]
bool isString()
const;
557 [[nodiscard]]
bool isBool()
const;
608 void checkValidType() {
609 if (!Setting::isValidType<T>()) {
610 std::ostringstream err;
611 err <<
"Setting does not support ";
612 err <<
"type \"" <<
typeid(T).name() <<
"\"";
613 throw std::invalid_argument(err.str());
Store a roadrunner option (or setting) as a Variant type.
Definition: Setting.h:78
std::string toString()
gets a string representation of the type stored in this Setting.
Definition: Setting.cpp:161
Setting()=default
default constructor.
bool isDoubleVector() const
true if this is a std::vector of doubles
Definition: Setting.cpp:50
T * get_if()
get the value of this Setting as type T if the value in this Setting is of type T.
Definition: Setting.h:183
TypeId type() const
returns the type of std::variant contained within this Setting.
Definition: Setting.cpp:22
bool isString() const
is this variant a std::string.
Definition: Setting.cpp:26
bool isDouble() const
true if this is a double
Definition: Setting.cpp:54
bool isEmpty() const
true if empty.
Definition: Setting.cpp:42
const std::type_info & typeInfo() const
returns the std::type_info for the object type contained within this Setting.
Definition: Setting.cpp:139
SettingType get()
return the value held by this Setting as a type SettingType.
Definition: Setting.h:197
const setting_t & getValue() const
getter for the std::variant_t underlying this Setting.
Definition: Setting.cpp:71
As getAs() const
explicitly convert this Setting to type As.
Definition: Setting.h:213
bool isType()
determines whether the current value of Setting is of type T.
Definition: Setting.h:163
static bool isValidType()
test for membership of type T in setting_t, aka supported types
Definition: Setting.h:172
decltype(auto) visit(Func function) const
equality operator for comparing object otherSetting of type T against the Setting contained within th...
Definition: Setting.h:490
bool isNumeric() const
is this a numeric type.
Definition: Setting.cpp:34
bool isSigned() const
true if this is a signed number.
Definition: Setting.cpp:46
std::string pythonRepr() const
Convert to Python-compatible representation.
Definition: Setting.cpp:58
Setting(T settingValue)
constructor for creating a Setting from a supperted type T.
Definition: Setting.h:98
static Setting parse(std::string &val)
Parses the std::string which must be in JSON format.
Definition: Setting.cpp:75
bool isInteger() const
was an integer stored here.
Definition: Setting.cpp:30
Setting & operator=(const Setting &setting)
move assignment operator for when rhs is a Setting.
Definition: Setting.cpp:119
TypeId
types that correspond to the index of the position of the type in the variant template.
Definition: Setting.h:132
bool isBool() const
is this a boolean type.
Definition: Setting.cpp:38
SettingType get() const
return the value held by this setting as type SettingType.
Definition: Setting.h:321
Generic type checking mechanism for membership of type T in variant ALL_T.
Definition: setting_t.h:38