roadrunner  2.6.0
Fast simulator for SBML models
Public Types | Public Member Functions | Static Public Member Functions | List of all members
rr::Setting Class Reference

Store a roadrunner option (or setting) as a Variant type. More...

#include <Setting.h>

Public Types

enum  TypeId {
  EMPTY = 0 , STRING = 1 , BOOL = 2 , INT32 = 3 ,
  UINT32 = 4 , INT64 = 5 , UINT64 = 6 , FLOAT = 7 ,
  DOUBLE = 8 , CHAR = 9 , UCHAR = 10 , DOUBLEVECTOR = 11
}
 types that correspond to the index of the position of the type in the variant template. More...
 

Public Member Functions

 Setting (setting_t value)
 constructor to take any type accepted by setting_t and store as a variant.
 
template<class T >
 Setting (T settingValue)
 constructor for creating a Setting from a supperted type T. More...
 
 Setting (const char *settingValue)
 constructor for enabling creation of a Setting from a string literal. More...
 
 Setting (std::int64_t settingValue)
 construct from a long. More...
 
 Setting ()=default
 default constructor. More...
 
TypeId type () const
 returns the type of std::variant contained within this Setting. More...
 
template<class T >
bool isType ()
 determines whether the current value of Setting is of type T. More...
 
template<class T >
T * get_if ()
 get the value of this Setting as type T if the value in this Setting is of type T. More...
 
template<class SettingType >
SettingType get ()
 return the value held by this Setting as a type SettingType. More...
 
template<class As >
As getAs () const
 explicitly convert this Setting to type As. More...
 
template<class SettingType >
SettingType get () const
 return the value held by this setting as type SettingType. More...
 
template<typename T >
 operator T () const
 implicit type conversion support for the Setting class. More...
 
 operator std::vector< double > ()
 implicit cast this Setting to a std::vector<double>. More...
 
template<class Func >
decltype(auto) visit (Func function) const
 equality operator for comparing object otherSetting of type T against the Setting contained within this Setting.value_. More...
 
const std::type_info & typeInfo () const
 returns the std::type_info for the object type contained within this Setting. More...
 
Settingoperator= (const Setting &setting)
 move assignment operator for when rhs is a Setting. More...
 
Settingoperator= (Setting &&setting) noexcept
 Move assignment operator for Setting with another Setting.
 
 Setting (const Setting &setting)
 Copy constructor for Setting with another Setting.
 
 Setting (Setting &&setting) noexcept
 Move constructor for Setting with another Setting.
 
const setting_t & getValue () const
 getter for the std::variant_t underlying this Setting.
 
std::string pythonRepr () const
 Convert to Python-compatible representation. More...
 
bool isString () const
 is this variant a std::string.
 
bool isInteger () const
 was an integer stored here.
 
bool isNumeric () const
 is this a numeric type.
 
bool isBool () const
 is this a boolean type.
 
bool isEmpty () const
 true if empty.
 
bool isSigned () const
 true if this is a signed number.
 
bool isDoubleVector () const
 true if this is a std::vector of doubles
 
bool isDouble () const
 true if this is a double
 
std::string toString ()
 gets a string representation of the type stored in this Setting.
 

Static Public Member Functions

template<class T >
static bool isValidType ()
 test for membership of type T in setting_t, aka supported types
 
static Setting parse (std::string &val)
 Parses the std::string which must be in JSON format. More...
 

Detailed Description

Store a roadrunner option (or setting) as a Variant type.

Uses a std::variant to hold one of the following types , std::monostate, std::string, bool, std::int32_t, std::uint32_t, std::int64_t, std::uint64_t, float, double, char, unsigned char, std::vector<double>

Note
for developers: order of the std::variant template specialization is important. Make sure the order always matches the other of the Setting::TypeId enum.
The function of this class used to be performed by rr::Variant. Since C++17 we have replaced this with a standard type.
// implicit type conversions
Setting setting(4); // is an int
int s = setting.get<int>(); // okay
int t = setting.get<std::string>(); // not okay, setting contains an int
auto u = setting.get_if<int>(); // u is pointer to int if setting is int else nullptr
if (auto v = setting.get_if<int>()){
// do something in context where `setting` is int
}
Setting setting2(-4); // contains an int with negative value
int q = setting2; // okay
long r = setting2; // okay
unsigned int w = setting2; // error, setting2 contains negative value
unsigned long x = setting2; // error, setting2 contains negative value
long biggest_int = std::numeric_limits<int>::max();
long out_of_range = biggest_int * 10;
Setting setting(out_of_range);
int x = setting; // error, int isn't big enough to hold `out_out_range`
// equality works as expected
Setting setting3(std::int64_t(12345678912345));
Setting setting4(std::int64_t(12345678912345));
ASSERT_TRUE(setting3 == setting4); // pass
ASSERT_TRUE(setting3 == 12345678912345); // also okay
// reassign a setting to different type
Setting setting5(123);
setting5 = "Now a string"; // okay
std::string expected = "Now a string";
ASSERT_TRUE(setting5 == expected); // pass
// instantiating a setting from other objects
std::string st = "A String";
Setting setting6(st); //okay
Setting setting7 = st ; // not okay
Setting setting8 = "A string"; // not okay
// check if Setting supports a type
bool supported = Setting::isValidType<int>(); // true
supported = Setting::isValidType<std::string>(); // true
supported = Setting::isValidType<const char*>(); // false
Setting()=default
default constructor.

Member Enumeration Documentation

◆ TypeId

types that correspond to the index of the position of the type in the variant template.

i.e. std::string is index 0.

Constructor & Destructor Documentation

◆ Setting() [1/4]

template<class T >
rr::Setting::Setting ( settingValue)
inline

constructor for creating a Setting from a supperted type T.

See also
setting_t for supported types

for developers: clang-tidy will want you to make this constructor explicit. However, we intentionally keep implicit to allow type casting from type T to Setting.

◆ Setting() [2/4]

rr::Setting::Setting ( const char *  settingValue)

constructor for enabling creation of a Setting from a string literal.

The literal gets converted into a std::string

Setting s("a string"); //interpreted as string, not const char*

◆ Setting() [3/4]

rr::Setting::Setting ( std::int64_t  settingValue)
explicit

construct from a long.

(std::int64_t is a long long, which matters on windows)

◆ Setting() [4/4]

rr::Setting::Setting ( )
default

default constructor.

Allows instantiating of an empty setting. The empty setting will have a type of std::monostate, which is index 0 in setting_t

Member Function Documentation

◆ get() [1/2]

template<class SettingType >
SettingType rr::Setting::get ( )
inline

return the value held by this Setting as a type SettingType.

simple wrapper around std::get.

Note
for developers. This is a replacement for rr::Variant::convert in legacy roadrunner. The name "get" is preferred to "convert" since it follows C++ standard conventions.

◆ get() [2/2]

template<class SettingType >
SettingType rr::Setting::get ( ) const
inline

return the value held by this setting as type SettingType.

const version of SettingType::get()

See also
SettingType::get()

◆ get_if()

template<class T >
T* rr::Setting::get_if ( )
inline

get the value of this Setting as type T if the value in this Setting is of type T.

wrapper around std::get_if

◆ getAs()

template<class As >
As rr::Setting::getAs ( ) const
inline

explicitly convert this Setting to type As.

type contained by this Setting must be readily convertible to type As and throws std::invalid_argument if not.

Setting setting(5);
ASSERT_EQ(setting.get<int>(), 5); // fails if setting is not int
ASSERT_THROW(setting.get<unsigned int>();, std::bad_variant_access); // bad, setting contains an int
ASSERT_EQ(setting.getAs<unsigned int>(), 5); // Okay, we can convert from int to unsigned (when int > 0)

◆ isType()

template<class T >
bool rr::Setting::isType ( )
inline

determines whether the current value of Setting is of type T.

Returns
true is Setting is of type T

◆ operator std::vector< double >()

rr::Setting::operator std::vector< double > ( )
inline

implicit cast this Setting to a std::vector<double>.

If this operator is used and the type contained by this Setting is not a double vector, an std::invalid_argument error is thrown.

the generic operator T() method does not cover the case when we have a vector of doubles, so we must implement this manually. We could write another template for the more general case, but only support for std::vector<double> is needed.

◆ operator T()

template<typename T >
rr::Setting::operator T ( ) const
inline

implicit type conversion support for the Setting class.

this method is responsible for enabling implicit conversion between Setting and its supported types. Moreover, it enables one to implicitly convert (say) a int to a long, in contexts that make sense (as determined by std::is_convertible_v). Some situations are explicitly prohibited from implicit type conversion. These include

  • converting a negative int or long to unsigned int or long
  • converting a long that has a value > the largest possible value for int to int
    Note
    for developers: clang-tidy will ask you to make this explicit, but this method must not be explicit since its entire purpose is implicit type conversion.
    for developers: Any additions to types stored in a setting_t must have appropriate unit tests added for the new types in SettingTests.cpp.

◆ operator=()

Setting & rr::Setting::operator= ( const Setting setting)

move assignment operator for when rhs is a Setting.

See also
operator=(const T&setting);

◆ parse()

Setting rr::Setting::parse ( std::string &  val)
static

Parses the std::string which must be in JSON format.

This is a common way to read a Variant from a file or create a new one from a std::string:

Variant v = Variant::parse("0.123");
static Variant parse(const std::string &val)
Parses the std::string which must be in JSON format.
Definition: _Variant.cpp:140
Note
this function is a tangent to the main Setting class. We should instead have a JSON parser, is that's the function we need.

◆ pythonRepr()

std::string rr::Setting::pythonRepr ( ) const

Convert to Python-compatible representation.

Author
JKM

◆ type()

Setting::TypeId rr::Setting::type ( ) const

returns the type of std::variant contained within this Setting.

Returns
an integer which refers to the index of the type contained in this Setting. The index is resolved by looking at the TypeId enum (or indeed the ordering of the type parameters to setting_t.

◆ typeInfo()

const std::type_info & rr::Setting::typeInfo ( ) const

returns the std::type_info for the object type contained within this Setting.

(aka one of the types within setting_t)

◆ visit()

template<class Func >
decltype(auto) rr::Setting::visit ( Func  function) const
inline

equality operator for comparing object otherSetting of type T against the Setting contained within this Setting.value_.

Enables the following types of comparisons

Setting s1("string");
std::string s2 = "string";
s1 == s2; // true
// or
Setting s3(1234);
int s4 = 1234;
s3 == s4; // true
@details Implemented using SFINAE - substitute failure is not an error.
The seconds template argument is only true when type T is a valid variant
and when this argument evaluates to false, the compiler will not generate
a code for the template types. Thus, this template is only defined for
types that are a part of setting_t.
/
template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>::type>
bool operator==(const T &otherSetting) {
if (auto settingValue = get_if<T>()) {
return *settingValue == otherSetting;
}
return false;
}
template<typename T,
class = typename std::enable_if<isValidVariantType<T, setting_t>::value>::type>
bool operator!=(const T &setting) {
return !(*this == setting);
}
bool operator==(const Setting &setting);
bool operator==(const char *setting);
bool operator!=(const char *setting);
bool operator!=(const Setting &setting);
template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>::type>
Setting &operator=(const T &setting) {
checkValidType<T>();
// no need to check self assignment with variant
value_ = setting_t(setting);
return *this;
}
template<typename T, class = typename std::enable_if<isValidVariantType<T, setting_t>::value>::type>
Setting &operator=(T &&setting) noexcept {
checkValidType<T>();
// no need to check self assignment with variant
value_ = std::move(setting_t(setting));
return *this;
}
TypeId type() const
returns the type of std::variant contained within this Setting.
Definition: Setting.cpp:22
Setting & operator=(const Setting &setting)
move assignment operator for when rhs is a Setting.
Definition: Setting.cpp:119
See also
docs on std::visit

The documentation for this class was generated from the following files: