diff --git a/const_fmt/format.h b/const_fmt/format.h index f84572c..cc8b0c3 100644 --- a/const_fmt/format.h +++ b/const_fmt/format.h @@ -47,7 +47,7 @@ constexpr inline void format_arg(char* dest, arg_t arg) { template constexpr inline void format_arg(char* dest, arg_t arg){ -// const_fmt_detail::format_float(dest, arg); + const_fmt_detail::format_float(dest, arg); }; // TODO: Error handling diff --git a/const_fmt/format_impl.h b/const_fmt/format_impl.h index 3cb9af1..3fe0359 100644 --- a/const_fmt/format_impl.h +++ b/const_fmt/format_impl.h @@ -112,6 +112,25 @@ constexpr inline void format_decimal(char* out, uint_t value, int n_digits, copy2(out, digits2(static_cast(value))); } +// returns {abs_value, was_negative} +template +constexpr std::pair::type, bool> +get_abs_value(int_t value) { + using uint_t = typename std::make_unsigned::type; + + uint_t abs_value = static_cast(value); + + const bool negative = value < 0; + if (negative) abs_value = 0 - abs_value; + + return {abs_value, negative}; +} + +template +constexpr std::pair get_abs_value(int_t value) { + return {value, false}; +} + /* * @@ -127,9 +146,7 @@ constexpr inline void format_int(char* out, uint_t value) { template constexpr inline void format_int(char* out, int_t value) { - uint64_t abs_value = static_cast(value); - const bool negative = value < 0; - if (negative) abs_value = 0 - abs_value; + const auto [abs_value, negative] = get_abs_value(value); const int n_digits = count_digits(abs_value); @@ -153,9 +170,34 @@ constexpr inline void format_int(char* out, int_t value) { template constexpr inline void format_float(char* out, float_t value) { + // clang-format off + constexpr fmt_data_t fmt_node_integral = { + t_fmt_node.has_zero_padding, // has_zero_padding + t_fmt_node.length - t_fmt_node.precision - 1, // length + t_fmt_node.precision, // ignored + t_fmt_node.type, // ignored + t_fmt_node.position // ignored + }; + constexpr fmt_data_t fmt_node_fractional = { + true, // has_zero_padding + t_fmt_node.precision, // length + t_fmt_node.precision, // ignored + t_fmt_node.type, // ignored + t_fmt_node.position // ignored + }; + // clang-format on - *(out) = 'f'; *(out + t_fmt_node.length - t_fmt_node.precision - 1) = '.'; + + const int integral = static_cast(value); + + constexpr std::size_t factor = const_pow(10, t_fmt_node.precision); + const int fractional = static_cast((value - integral) * factor); + + const auto [fractional_abs, fractional_negative] = get_abs_value(fractional); + + format_int(out, integral); + format_int(out + t_fmt_node.length - t_fmt_node.precision, fractional_abs); } diff --git a/examples/src/examples.cpp b/examples/src/examples.cpp index 4769151..82ab7ea 100644 --- a/examples/src/examples.cpp +++ b/examples/src/examples.cpp @@ -5,7 +5,7 @@ using namespace const_fmt; int main() { - constexpr auto s = "abcdef {:04}"_const_fmt(123); + constexpr auto s = "abcdef {:9.3}"_const_fmt(-876.3); // Convert s (with a type of 'std::array') into something // writable to std::cout