toml11
toml11 copied to clipboard
Type conversion between numeric types
In the README it mentions that conversion between int/floating cannot be done implicitly. Is this really not possible? If a user wants to set a starting position vector as the origin, having
[start]
position = [0,0,0]
fail to be read by toml::get<std::vector<double>>(start_table.at("position"))
is quite frustrating. I appreciate that doing implicit lossy conversions (1.2
as an int for example) might be an implementation choice, but the inability to get 0
as a double seems to be a bit arbitrary. If it is technically possible but not something you feel the need to implement, then I might have a look.
Thanks for the great library!
I basically agree with your point, it would be more useful if it can convert int64_t into float and vice versa. But there is a reason why it is not supported.
When we specify a type that does not require any type conversion, it returns a reference (like int64_t&
) that enables us to modify the content through it.
int64_t& x = toml::find<int64_t>(input, "x");
x = 42; // overwrite "x" in `input`
But, it is not possible to bind int64_t
as a reference to other type, like double&
. double
is one of the types that is contained in the internal storage of toml::value
and does not require type conversion (if the toml::value
contains Float
value). So if double
is specified as a template argument of toml::get
, it should returns double&
, for the sake of consistency. Here, if the value actually contains int64_t
, we cannot bind it to double&
and the return type must be double
. The problem is that we cannot know the actual contained type before parsing a file. If we want to support conversion, the return type of toml::get
(whether it is a reference or a value) should be determined after checking what value is contained, that means that the type should be changed at runtime, and it is impossible.
So the available options are
- returning a value by copy. conversion via
toml::get
becomes handy, but modification is impossible. (breaking change) - returning a value by reference. conversion via
toml::get
has restriction, but modification is possible. (current implementation) - returning a wrapper type that automatically casts a value in assignment operator, and making the code complicated. (breaking change)
- add a totally new function, that might be named as
toml::as<T>
, that always returns a value instead of reference. (minor update)
I think the most feasible option is the last one.
Understood, I hadn't appreciated the reference problem. To forge ahead, I worked around it in my code with a simple toml::find
wrapper template that if the return type template std::is_floating_point<T>::value
is true, then it uses a specialization that checks at runtime if the parsed type is_integer()
with the toml::value
methods and if it is does the conversion.
Your proposed solution sounds perfect though, thank you for taking the time to read and think about my question!
Could it give a warning if a key exists but with wrong type?