#ifndef LOGGER_FORMAT_H #define LOGGER_FORMAT_H #include "parse.h" 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"); unsigned result = 0; for (const auto& ast_node : parse_result.value) { if (ast_node.is_char()) ++result; else result += ast_node.get_node().length; } 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"); std::array result; for (auto& c : result) c = 'f'; 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...); } else { 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); return format_args(result, first_arg, other_args...); } } } } // namespace detail template std::array()> format(args_t... args) { constexpr auto parse_result = detail::parse_string(); static_assert(parse_result.is_valid); std::array()> result; return detail::format_args(result, args...); } #endif // LOGGER_FORMAT_H