format_arg(float) now works with the desired precision
This commit is contained in:
parent
ce2006694e
commit
f2de0773ed
51
inc/format.h
51
inc/format.h
@ -3,10 +3,16 @@
|
||||
|
||||
|
||||
#include "parse.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<fmt_node_t fmt_node, typename T>
|
||||
constexpr void check_fmt_params() {
|
||||
static_assert(fmt_node.length > fmt_node.precision + 1, "Insufficient length for desired precision");
|
||||
}
|
||||
|
||||
|
||||
template <ConstString s>
|
||||
constexpr int get_output_len() {
|
||||
@ -28,50 +34,78 @@ constexpr int get_output_len() {
|
||||
|
||||
template <fmt_node_t fmt_node, std::integral arg_t>
|
||||
constexpr std::array<char, fmt_node.length> format_arg(arg_t arg) {
|
||||
check_fmt_params<fmt_node, arg_t>();
|
||||
|
||||
std::array<char, fmt_node.length> result;
|
||||
|
||||
// TODO: See if this is possible with charconv
|
||||
for (unsigned i = 1; i <= result.size(); ++i) {
|
||||
result[result.size() - i] = arg % 10 + 48;
|
||||
arg = arg / 10;
|
||||
arg = arg / 10;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <fmt_node_t fmt_node, std::floating_point arg_t>
|
||||
constexpr std::array<char, fmt_node.length> format_arg(arg_t) {
|
||||
constexpr std::array<char, fmt_node.length> format_arg(arg_t arg) {
|
||||
check_fmt_params<fmt_node, arg_t>();
|
||||
|
||||
std::array<char, fmt_node.length> result;
|
||||
|
||||
constexpr unsigned len_before_point =
|
||||
fmt_node.length - fmt_node.precision - 1;
|
||||
|
||||
result[result.size() - fmt_node.precision - 1] = '.';
|
||||
|
||||
// TODO: See if this is possible with charconv
|
||||
for (auto& c : result)
|
||||
c = 'f';
|
||||
|
||||
constexpr unsigned multiplier = const_pow(10, fmt_node.precision);
|
||||
arg = arg * multiplier;
|
||||
|
||||
for (unsigned i = result.size()-1; i >= result.size() - fmt_node.precision; --i) {
|
||||
result[i] = static_cast<int>(arg) % 10 + 48;
|
||||
arg = arg / 10;
|
||||
}
|
||||
|
||||
for (unsigned i = fmt_node.precision + 2; i <= result.size(); ++i) {
|
||||
result[result.size() - i] = static_cast<int>(arg) % 10 + 48;
|
||||
arg = arg / 10;
|
||||
}
|
||||
|
||||
/*
|
||||
for (unsigned i = fmt_node.precision + 1; i <= result.size(); ++i) {
|
||||
result[result.size() - i] = static_cast<int>(arg) % 10 + 48;
|
||||
arg = arg / 10;
|
||||
}
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <fmt_node_t fmt_node>
|
||||
constexpr std::array<char, fmt_node.length> format_arg(const char* arg) {
|
||||
check_fmt_params<fmt_node, const char*>();
|
||||
|
||||
std::array<char, fmt_node.length> result;
|
||||
|
||||
for (auto& c : result) {
|
||||
if (*arg != '\0')
|
||||
c = *(arg++);
|
||||
else
|
||||
c = '-';
|
||||
c = '_';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <auto t_ast, unsigned t_ast_i = 0, unsigned t_result_i = 0,
|
||||
typename char_array_t>
|
||||
typename char_array_t>
|
||||
constexpr char_array_t format_args(char_array_t result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <auto t_ast, unsigned t_ast_i = 0, unsigned t_result_i = 0,
|
||||
typename char_array_t, typename first_arg_t, typename... other_args_t>
|
||||
constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg,
|
||||
@ -93,7 +127,8 @@ constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg,
|
||||
result.begin() + t_result_i);
|
||||
|
||||
return format_args<t_ast, t_ast_i + 1,
|
||||
t_result_i + fmt_node.length>(result, other_args...);
|
||||
t_result_i + fmt_node.length>(result,
|
||||
other_args...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
inc/utility.h
Normal file
19
inc/utility.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef LOGGER_UTILITY_H
|
||||
#define LOGGER_UTILITY_H
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
constexpr std::size_t const_pow(std::size_t base, std::size_t pow) {
|
||||
if (pow == 0)
|
||||
return 1;
|
||||
else
|
||||
return base * const_pow(base, pow - 1);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
#endif // LOGGER_UTILITY_H
|
||||
@ -12,7 +12,7 @@ public:
|
||||
|
||||
|
||||
int main() {
|
||||
constexpr auto formatted = format<"Test: {:3.8f} {:5.5} {:05.2}">(3.4, "abc", 1234);
|
||||
const auto formatted = format<"Test: {:8.3} {:6.3} {:05.2}">(1432.4334, "abc", 1234);
|
||||
|
||||
for (const auto& c : formatted)
|
||||
std::cout << c;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user