From 53091a30cd6ad8b22ac31b4a571594ecf6d16f76 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 21 Nov 2021 18:52:07 +0100 Subject: [PATCH] Added format_arg() for integral and floating point types and char arrays --- inc/format.h | 71 ++++++++++++++++++++++++++++++++++++++-------------- src/main.cpp | 4 +-- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/inc/format.h b/inc/format.h index d65ad46..0446e90 100644 --- a/inc/format.h +++ b/inc/format.h @@ -11,7 +11,7 @@ namespace detail { template constexpr int get_output_len() { constexpr auto parse_result = parse_string(); - 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; @@ -25,42 +25,75 @@ constexpr int get_output_len() { return result; } -template -constexpr bool is_valid_type() { - // TODO - return true; -} - -template -constexpr std::array format_arg(T arg) { - static_assert(is_valid_type(), "Invalid argument type"); +template +constexpr std::array format_arg(arg_t arg) { std::array 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 +constexpr std::array format_arg(arg_t) { + std::array result; + + // TODO: See if this is possible with charconv for (auto& c : result) c = 'f'; return result; } +template +constexpr std::array format_arg(const char* arg) { + std::array result; -template -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()) { + for (auto& c : result) { + if (*arg != '\0') + c = *(arg++); + else + c = '-'; + } + + return result; +} + +template +constexpr char_array_t format_args(char_array_t result) { + return result; +} + + + +template +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()) { return result; } else { constexpr auto ast_node = t_ast[t_ast_i]; if (ast_node.is_char()) { result[t_result_i] = ast_node.get_char(); - return format_args(result, first_arg, other_args...); + return format_args( + result, first_arg, other_args...); } else { - constexpr auto fmt_node = ast_node.get_node(); - const auto formatted_arg = format_arg(first_arg); + constexpr auto fmt_node = ast_node.get_node(); + const auto formatted_arg = format_arg(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(result, first_arg, other_args...); + return format_args(result, other_args...); } } } @@ -72,7 +105,7 @@ constexpr char_array_t format_args(char_array_t result, first_arg_t first_arg, o template std::array()> format(args_t... args) { constexpr auto parse_result = detail::parse_string(); - static_assert(parse_result.is_valid); + static_assert(parse_result.is_valid, "Syntax error in format string"); std::array()> result; diff --git a/src/main.cpp b/src/main.cpp index 7c4986b..5fb0e56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,9 +12,7 @@ public: int main() { - constexpr detail::ConstString s{"Test: {:3.8f} {:02.5} {:05.2}"}; - - const auto formatted = format(3.4, "abc", 8.98754); + const auto formatted = format<"Test: {:3.8f} {:5.5} {:05.2}">(3.4, "abc", 1234); for (const auto& c : formatted) std::cout << c;