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 havefrom_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
(likeboost::lexical_cast
) cast
-
toNumber
(inversion ofstd::to_string
) toArithmetic
fromString
-
fromChars
(similar tostd::from_chars
but with different signature) parseString
-
parse
(likeParameterTree::Parser<T>::parse
) -
strToNumber
(likestd::strtof
)
TODO
-
Replace test that uses random number, with a deterministic test of corner cases