Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type conversion between numeric types #140

Open
luketpickering opened this issue Oct 20, 2020 · 3 comments
Open

Type conversion between numeric types #140

luketpickering opened this issue Oct 20, 2020 · 3 comments

Comments

@luketpickering
Copy link

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!

@ToruNiina
Copy link
Owner

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.

@luketpickering
Copy link
Author

luketpickering commented Oct 22, 2020

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!

@xgdgsc
Copy link

xgdgsc commented Oct 14, 2021

Could it give a warning if a key exists but with wrong type?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants