#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/integer_to_string.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace details {
template <typename T>
using ZeroPaddedHexFmt = IntegerToString<
T, typename radix::Hex::WithWidth<(sizeof(T) * 2)>::WithPrefix::Uppercase>;
}
template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
using StorageType = typename fputil::FPBits<T>::StorageType;
if (x.is_nan())
return "(NaN)";
if (x.is_inf())
return x.is_neg() ? "(-Infinity)" : "(+Infinity)";
const auto sign_char = [](Sign sign) -> char {
return sign.is_neg() ? '1' : '0';
};
cpp::string s;
const details::ZeroPaddedHexFmt<StorageType> bits(x.uintval());
s += bits.view();
s += " = (S: ";
s += sign_char(x.sign());
s += ", E: ";
const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
s += exponent.view();
if constexpr (fputil::get_fp_type<T>() == fputil::FPType::X86_Binary80) {
s += ", I: ";
s += sign_char(x.get_implicit_bit() ? Sign::NEG : Sign::POS);
}
s += ", M: ";
const details::ZeroPaddedHexFmt<StorageType> mantissa(x.get_mantissa());
s += mantissa.view();
s += ')';
return s;
}
}
#endif