Skip to content

WIP: A generic string-to-number conversion function

Summary

Add facility to cast from character sequence to any number type, implemented in terms of std library functions like atoi() and strf() but parametrized with the concrete target type for ease of usage in generic code.

Motivation

There is not generic string-to-number conversion function in the std library, except for std::ostringstream. But, the latter is quite slow compared to type specific functions like strtof() (about a factor of 10 slower) and needs about 3 lines of code compared to a direct conversion function. In other libraries, like boost, generic functions for string-to-number conversions are added that are much faster that the intrinsics. Here a very simple approach is used to get a generic converter, but simply specializing a helper function on the concrete number type and calling the type-specific std function.

Application

I have in mind the conversion of quadrature points and weights in dune-geometry from a string representation of the number, to allow high-precision data to be used.

Discussion

Locale independent implementation

When using std library functions, like std::strtof these are locale dependent, meaning that e.g. the decimal dot may be different on different systems leading to different behavior of the code. Do we need locale independent conversion, e.g. for parsing ini files or for converting stored quadrature values? Or is the user responsible for setting the correct locale setting in its main program?

  • Locale independent conversion is currently only possible with std::stringstream, with c++17 we may have from_chars but there is no working implementation in any std library, currently.
  • Locale dependent implementation can be done with any strtof like functions. Additionaly, a check can be implemented that throws an error if the string can not be parsed correctly in the current locale setting.

Alternatives

The simplest alternative is std::ostringstream, but as explained above, it has the drawback of slow performance and not so easy to use. A second alternative is ParameterTree::Parser<T>::parse(...), but it is a private implementation details of the ParameterTree class and uses std::stringstream internally.

The usage of these std library functions has the drawback of little error safety, i.e. for atoi the default behavior is: If the converted value falls out of range of corresponding return type, the return value is undefined. If no conversion can be performed, ​0​ is returned. But on the other hand it gives high performance in conversion, what is intended here.

Naming

Alternative feature names could be considered:

  • lexicalCast (like boost::lexical_cast)
  • cast
  • toNumber (inversion of std::to_string)
  • toArithmetic
  • fromString
  • fromChars (similar to std::from_chars but with different signature)
  • parseString
  • parse (like ParameterTree::Parser<T>::parse)
  • strToNumber (like std::strtof)

TODO

  • Replace test that uses random number, with a deterministic test of corner cases
Edited by Christian Engwer

Merge request reports