#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/detailed_powers_of_ten.h"
#include "src/__support/high_precision_decimal.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/null_check.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/str_to_integer.h"
#include "src/__support/str_to_num_result.h"
#include "src/__support/uint128.h"
#include "src/errno/libc_errno.h"
#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
template <class T> struct ExpandedFloat { … };
template <class T> struct FloatConvertReturn { … };
LIBC_INLINE uint64_t low64(const UInt128 &num) { … }
LIBC_INLINE uint64_t high64(const UInt128 &num) { … }
template <class T> LIBC_INLINE void set_implicit_bit(fputil::FPBits<T> &) { … }
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <>
LIBC_INLINE void
set_implicit_bit<long double>(fputil::FPBits<long double> &result) { … }
#endif
template <class T>
LIBC_INLINE cpp::optional<ExpandedFloat<T>>
eisel_lemire(ExpandedFloat<T> init_num,
RoundDirection round = RoundDirection::Nearest) { … }
#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
template <>
LIBC_INLINE cpp::optional<ExpandedFloat<long double>>
eisel_lemire<long double>(ExpandedFloat<long double> init_num,
RoundDirection round) { … }
#endif
constexpr uint8_t POWERS_OF_TWO[19] = …;
constexpr int32_t NUM_POWERS_OF_TWO = …;
template <class T>
LIBC_INLINE FloatConvertReturn<T> simple_decimal_conversion(
const char *__restrict numStart,
const size_t num_len = cpp::numeric_limits<size_t>::max(),
RoundDirection round = RoundDirection::Nearest) { … }
template <class T> class ClingerConsts;
template <> class ClingerConsts<float> { … };
template <> class ClingerConsts<double> { … };
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
template <> class ClingerConsts<long double> {
public:
static constexpr long double POWERS_OF_TEN_ARRAY[] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
static constexpr int32_t EXACT_POWERS_OF_TEN =
ClingerConsts<double>::EXACT_POWERS_OF_TEN;
static constexpr int32_t DIGITS_IN_MANTISSA =
ClingerConsts<double>::DIGITS_IN_MANTISSA;
static constexpr long double MAX_EXACT_INT =
ClingerConsts<double>::MAX_EXACT_INT;
};
#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
template <> class ClingerConsts<long double> { … };
#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
template <> class ClingerConsts<long double> {
public:
static constexpr long double POWERS_OF_TEN_ARRAY[] = {
1e0L, 1e1L, 1e2L, 1e3L, 1e4L, 1e5L, 1e6L, 1e7L, 1e8L, 1e9L,
1e10L, 1e11L, 1e12L, 1e13L, 1e14L, 1e15L, 1e16L, 1e17L, 1e18L, 1e19L,
1e20L, 1e21L, 1e22L, 1e23L, 1e24L, 1e25L, 1e26L, 1e27L, 1e28L, 1e29L,
1e30L, 1e31L, 1e32L, 1e33L, 1e34L, 1e35L, 1e36L, 1e37L, 1e38L, 1e39L,
1e40L, 1e41L, 1e42L, 1e43L, 1e44L, 1e45L, 1e46L, 1e47L, 1e48L};
static constexpr int32_t EXACT_POWERS_OF_TEN = 48;
static constexpr int32_t DIGITS_IN_MANTISSA = 33;
static constexpr long double MAX_EXACT_INT =
10384593717069655257060992658440191.0L;
};
#else
#error "Unknown long double type"
#endif
template <class T>
LIBC_INLINE cpp::optional<ExpandedFloat<T>>
clinger_fast_path(ExpandedFloat<T> init_num,
RoundDirection round = RoundDirection::Nearest) { … }
template <typename T> LIBC_INLINE constexpr int32_t get_upper_bound() { … }
template <> LIBC_INLINE constexpr int32_t get_upper_bound<float>() { … }
template <> LIBC_INLINE constexpr int32_t get_upper_bound<double>() { … }
template <typename T> LIBC_INLINE constexpr int32_t get_lower_bound() { … }
template <> LIBC_INLINE constexpr int32_t get_lower_bound<float>() { … }
template <> LIBC_INLINE constexpr int32_t get_lower_bound<double>() { … }
template <class T>
LIBC_INLINE FloatConvertReturn<T> decimal_exp_to_float(
ExpandedFloat<T> init_num, bool truncated, RoundDirection round,
const char *__restrict numStart,
const size_t num_len = cpp::numeric_limits<size_t>::max()) { … }
template <class T>
LIBC_INLINE FloatConvertReturn<T> binary_exp_to_float(ExpandedFloat<T> init_num,
bool truncated,
RoundDirection round) { … }
LIBC_INLINE bool is_float_hex_start(const char *__restrict src,
const char decimalPoint) { … }
template <class T>
LIBC_INLINE StrToNumResult<ExpandedFloat<T>>
decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
RoundDirection round) { … }
template <class T>
LIBC_INLINE StrToNumResult<ExpandedFloat<T>>
hexadecimal_string_to_float(const char *__restrict src,
const char DECIMAL_POINT, RoundDirection round) { … }
template <class T>
LIBC_INLINE typename fputil::FPBits<T>::StorageType
nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) { … }
template <class T>
LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) { … }
template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) { … }
}
}
#endif