mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add atof, strtof, strtod, strtold
This commit is contained in:
parent
28f7c510a5
commit
907bced466
7 changed files with 356 additions and 0 deletions
17
sprout/cstdlib/atof.hpp
Normal file
17
sprout/cstdlib/atof.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef SPROUT_CSTDLIB_ATOF_HPP
|
||||
#define SPROUT_CSTDLIB_ATOF_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstdlib/str_to_float.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// atof
|
||||
//
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR double atof(Char const* str){
|
||||
return sprout::str_to_float<double>(str);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_ATOF_HPP
|
|
@ -4,12 +4,17 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstdlib/ascii_to_int.hpp>
|
||||
#include <sprout/cstdlib/str_to_int.hpp>
|
||||
#include <sprout/cstdlib/str_to_float.hpp>
|
||||
#include <sprout/cstdlib/atoi.hpp>
|
||||
#include <sprout/cstdlib/atol.hpp>
|
||||
#include <sprout/cstdlib/atoll.hpp>
|
||||
#include <sprout/cstdlib/atof.hpp>
|
||||
#include <sprout/cstdlib/strtol.hpp>
|
||||
#include <sprout/cstdlib/strtoul.hpp>
|
||||
#include <sprout/cstdlib/strtoll.hpp>
|
||||
#include <sprout/cstdlib/strtoull.hpp>
|
||||
#include <sprout/cstdlib/strtof.hpp>
|
||||
#include <sprout/cstdlib/strtod.hpp>
|
||||
#include <sprout/cstdlib/strtold.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_CONVERSION_HPP
|
||||
|
|
255
sprout/cstdlib/str_to_float.hpp
Normal file
255
sprout/cstdlib/str_to_float.hpp
Normal file
|
@ -0,0 +1,255 @@
|
|||
#ifndef SPROUT_CSTDLIB_STR_TO_FLOAT_HPP
|
||||
#define SPROUT_CSTDLIB_STR_TO_FLOAT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/ctype/ascii.hpp>
|
||||
#include <sprout/utility/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_scale(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0,
|
||||
long n = 0,
|
||||
FloatType p10 = FloatType(10)
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return n ? sprout::detail::str_to_float_impl_scale<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
n & 1 ? (exponent < 0 ? number / p10 : number * p10) : number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent,
|
||||
n >> 1,
|
||||
p10 * p10
|
||||
)
|
||||
: number
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_exponent_2(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0,
|
||||
long n = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return exponent >= std::numeric_limits<FloatType>::min_exponent
|
||||
&& exponent <= std::numeric_limits<FloatType>::max_exponent
|
||||
? sprout::detail::str_to_float_impl_scale<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent,
|
||||
exponent < 0 ? -exponent : exponent
|
||||
)
|
||||
: HUGE_VAL
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_exponent_1(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0,
|
||||
long n = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return sprout::ascii::isdigit(*str) ? sprout::detail::str_to_float_impl_exponent_1<FloatType>(
|
||||
sprout::next(str),
|
||||
negative,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent,
|
||||
n * 10 + (*str - static_cast<char_type>('0'))
|
||||
)
|
||||
: sprout::detail::str_to_float_impl_exponent_2<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
negative ? exponent + n : exponent - n,
|
||||
n
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_exponent(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return (*str == static_cast<char_type>('e') || *str == static_cast<char_type>('E'))
|
||||
? *sprout::next(str) == static_cast<char_type>('-')
|
||||
? sprout::detail::str_to_float_impl_exponent_1<FloatType>(
|
||||
sprout::next(str, 2),
|
||||
true,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent
|
||||
)
|
||||
: sprout::detail::str_to_float_impl_exponent_1<FloatType>(
|
||||
sprout::next(str, 2),
|
||||
false,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent
|
||||
)
|
||||
: sprout::detail::str_to_float_impl_exponent_2<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_decimal_1(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return num_digits == 0 ? FloatType()
|
||||
: sprout::detail::str_to_float_impl_exponent<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
negative ? -number : number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl_decimal(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0,
|
||||
std::size_t num_decimals = 0,
|
||||
long exponent = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return sprout::ascii::isdigit(*str) ? sprout::detail::str_to_float_impl_decimal<FloatType>(
|
||||
sprout::next(str),
|
||||
negative,
|
||||
number * 10 + (*str - static_cast<char_type>('0')),
|
||||
num_digits + 1,
|
||||
num_decimals + 1,
|
||||
exponent
|
||||
)
|
||||
: sprout::detail::str_to_float_impl_decimal_1<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
number,
|
||||
num_digits,
|
||||
num_decimals,
|
||||
exponent - num_decimals
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float_impl(
|
||||
CStrIterator str,
|
||||
bool negative,
|
||||
FloatType number = FloatType(),
|
||||
std::size_t num_digits = 0
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<CStrIterator>::value_type char_type;
|
||||
return sprout::ascii::isdigit(*str) ? sprout::detail::str_to_float_impl<FloatType>(
|
||||
sprout::next(str),
|
||||
negative,
|
||||
number * 10 + (*str - static_cast<char_type>('0')),
|
||||
num_digits + 1
|
||||
)
|
||||
: *str == static_cast<char_type>('.') ? sprout::detail::str_to_float_impl_decimal<FloatType>(
|
||||
sprout::next(str),
|
||||
negative,
|
||||
number,
|
||||
num_digits
|
||||
)
|
||||
: sprout::detail::str_to_float_impl_decimal_1<FloatType>(
|
||||
str,
|
||||
negative,
|
||||
number,
|
||||
num_digits
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float(CStrIterator str) {
|
||||
return sprout::ascii::isspace(*str)
|
||||
? sprout::detail::str_to_float<FloatType>(sprout::next(str))
|
||||
: *str == static_cast<typename std::iterator_traits<CStrIterator>::value_type>('-')
|
||||
? sprout::detail::str_to_float_impl<FloatType>(sprout::next(str), true)
|
||||
: *str == static_cast<typename std::iterator_traits<CStrIterator>::value_type>('+')
|
||||
? sprout::detail::str_to_float_impl<FloatType>(sprout::next(str), false)
|
||||
: sprout::detail::str_to_float_impl<FloatType>(str, false)
|
||||
;
|
||||
}
|
||||
template<typename FloatType, typename CStrIterator, typename CharPtr>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float(CStrIterator str, CharPtr* endptr) {
|
||||
return !endptr ? sprout::detail::str_to_float<FloatType>(str)
|
||||
: std::strtod(str, endptr)
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// str_to_float
|
||||
//
|
||||
template<typename FloatType, typename Char>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float(Char const* str, Char** endptr) {
|
||||
return sprout::detail::str_to_float<FloatType>(str, endptr);
|
||||
}
|
||||
template<typename FloatType, typename Char>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float(Char const* str, std::nullptr_t endptr) {
|
||||
return sprout::detail::str_to_float<FloatType>(str);
|
||||
}
|
||||
template<typename FloatType, typename Char>
|
||||
inline SPROUT_CONSTEXPR FloatType str_to_float(Char const* str) {
|
||||
return sprout::detail::str_to_float<FloatType>(str);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_STR_TO_FLOAT_HPP
|
|
@ -6,6 +6,7 @@
|
|||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/ctype/ascii.hpp>
|
||||
#include <sprout/utility/enabler_if.hpp>
|
||||
#include <sprout/detail/char_conversion.hpp>
|
||||
|
||||
|
|
26
sprout/cstdlib/strtod.hpp
Normal file
26
sprout/cstdlib/strtod.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef SPROUT_CSTDLIB_STRTOD_HPP
|
||||
#define SPROUT_CSTDLIB_STRTOD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstdlib/str_to_float.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// strtod
|
||||
//
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR double strtod(Char const* str, Char** endptr){
|
||||
return sprout::str_to_float<double>(str, endptr);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR double strtod(Char const* str, std::nullptr_t endptr){
|
||||
return sprout::str_to_float<double>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR double strtod(Char const* str){
|
||||
return sprout::str_to_float<double>(str);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_STRTOD_HPP
|
26
sprout/cstdlib/strtof.hpp
Normal file
26
sprout/cstdlib/strtof.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef SPROUT_CSTDLIB_STRTOF_HPP
|
||||
#define SPROUT_CSTDLIB_STRTOF_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstdlib/str_to_float.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// strtof
|
||||
//
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR float strtof(Char const* str, Char** endptr){
|
||||
return sprout::str_to_float<float>(str, endptr);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR float strtof(Char const* str, std::nullptr_t endptr){
|
||||
return sprout::str_to_float<float>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR float strtof(Char const* str){
|
||||
return sprout::str_to_float<float>(str);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_STRTOF_HPP
|
26
sprout/cstdlib/strtold.hpp
Normal file
26
sprout/cstdlib/strtold.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef SPROUT_CSTDLIB_STRTOLD_HPP
|
||||
#define SPROUT_CSTDLIB_STRTOLD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstdlib/str_to_float.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// strtold
|
||||
//
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR long double strtold(Char const* str, Char** endptr){
|
||||
return sprout::str_to_float<long double>(str, endptr);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR long double strtold(Char const* str, std::nullptr_t endptr){
|
||||
return sprout::str_to_float<long double>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
inline SPROUT_CONSTEXPR long double strtold(Char const* str){
|
||||
return sprout::str_to_float<long double>(str);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTDLIB_STRTOLD_HPP
|
Loading…
Reference in a new issue