Added format_arg() for integral and floating point types and char arrays
This commit is contained in:
parent
6afb5bea87
commit
53091a30cd
65
inc/format.h
65
inc/format.h
@ -11,7 +11,7 @@ namespace detail {
|
|||||||
template <ConstString s>
|
template <ConstString s>
|
||||||
constexpr int get_output_len() {
|
constexpr int get_output_len() {
|
||||||
constexpr auto parse_result = parse_string<s>();
|
constexpr auto parse_result = parse_string<s>();
|
||||||
static_assert(parse_result.is_valid, "Syntax error in log string");
|
static_assert(parse_result.is_valid, "Syntax error in format string");
|
||||||
|
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
|
|
||||||
@ -25,27 +25,57 @@ constexpr int get_output_len() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, fmt_node_t fmt_node>
|
|
||||||
constexpr bool is_valid_type() {
|
|
||||||
// TODO
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <fmt_node_t fmt_node, typename T>
|
|
||||||
constexpr std::array<char, fmt_node.length> format_arg(T arg) {
|
|
||||||
static_assert(is_valid_type<T, fmt_node>(), "Invalid argument type");
|
|
||||||
|
|
||||||
|
template <fmt_node_t fmt_node, std::integral arg_t>
|
||||||
|
constexpr std::array<char, fmt_node.length> format_arg(arg_t arg) {
|
||||||
std::array<char, fmt_node.length> result;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <fmt_node_t fmt_node, std::floating_point arg_t>
|
||||||
|
constexpr std::array<char, fmt_node.length> format_arg(arg_t) {
|
||||||
|
std::array<char, fmt_node.length> result;
|
||||||
|
|
||||||
|
// TODO: See if this is possible with charconv
|
||||||
for (auto& c : result)
|
for (auto& c : result)
|
||||||
c = 'f';
|
c = 'f';
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <fmt_node_t fmt_node>
|
||||||
|
constexpr std::array<char, fmt_node.length> format_arg(const char* arg) {
|
||||||
|
std::array<char, fmt_node.length> 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>
|
for (auto& c : result) {
|
||||||
constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg, other_args_t... other_args) {
|
if (*arg != '\0')
|
||||||
|
c = *(arg++);
|
||||||
|
else
|
||||||
|
c = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <auto t_ast, unsigned t_ast_i = 0, unsigned t_result_i = 0,
|
||||||
|
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,
|
||||||
|
other_args_t... other_args) {
|
||||||
if constexpr (t_ast_i >= t_ast.size()) {
|
if constexpr (t_ast_i >= t_ast.size()) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@ -53,14 +83,17 @@ constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg, o
|
|||||||
|
|
||||||
if (ast_node.is_char()) {
|
if (ast_node.is_char()) {
|
||||||
result[t_result_i] = ast_node.get_char();
|
result[t_result_i] = ast_node.get_char();
|
||||||
return format_args<t_ast, t_ast_i+1, t_result_i+1>(result, first_arg, other_args...);
|
return format_args<t_ast, t_ast_i + 1, t_result_i + 1>(
|
||||||
|
result, first_arg, other_args...);
|
||||||
} else {
|
} else {
|
||||||
constexpr auto fmt_node = ast_node.get_node();
|
constexpr auto fmt_node = ast_node.get_node();
|
||||||
const auto formatted_arg = format_arg<fmt_node>(first_arg);
|
const auto formatted_arg = format_arg<fmt_node>(first_arg);
|
||||||
|
|
||||||
std::copy(formatted_arg.begin(), formatted_arg.end(), result.begin()+t_result_i);
|
std::copy(formatted_arg.begin(), formatted_arg.end(),
|
||||||
|
result.begin() + t_result_i);
|
||||||
|
|
||||||
return format_args<t_ast, t_ast_i+1, t_result_i+fmt_node.length>(result, first_arg, other_args...);
|
return format_args<t_ast, t_ast_i + 1,
|
||||||
|
t_result_i + fmt_node.length>(result, other_args...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,7 +105,7 @@ constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg, o
|
|||||||
template <detail::ConstString s, typename... args_t>
|
template <detail::ConstString s, typename... args_t>
|
||||||
std::array<char, detail::get_output_len<s>()> format(args_t... args) {
|
std::array<char, detail::get_output_len<s>()> format(args_t... args) {
|
||||||
constexpr auto parse_result = detail::parse_string<s>();
|
constexpr auto parse_result = detail::parse_string<s>();
|
||||||
static_assert(parse_result.is_valid);
|
static_assert(parse_result.is_valid, "Syntax error in format string");
|
||||||
|
|
||||||
std::array<char, detail::get_output_len<s>()> result;
|
std::array<char, detail::get_output_len<s>()> result;
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
constexpr detail::ConstString s{"Test: {:3.8f} {:02.5} {:05.2}"};
|
const auto formatted = format<"Test: {:3.8f} {:5.5} {:05.2}">(3.4, "abc", 1234);
|
||||||
|
|
||||||
const auto formatted = format<s>(3.4, "abc", 8.98754);
|
|
||||||
|
|
||||||
for (const auto& c : formatted)
|
for (const auto& c : formatted)
|
||||||
std::cout << c;
|
std::cout << c;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user