diff --git a/inc/format.h b/inc/format.h index 690c3e7..96596da 100644 --- a/inc/format.h +++ b/inc/format.h @@ -20,7 +20,7 @@ namespace detail { template -constexpr int get_output_len() { +constexpr inline int get_output_len() { constexpr auto parse_result = parse_string(); static_assert(parse_result.is_valid, "Syntax error in format string"); @@ -28,7 +28,7 @@ constexpr int get_output_len() { } template -constexpr void check_fmt_params() { +constexpr inline void check_fmt_params() { static_assert(fmt_node.length > fmt_node.precision + 1, "Insufficient length for desired precision"); } @@ -40,19 +40,21 @@ constexpr void check_fmt_params() { * */ - +// TODO: Error handling template -constexpr void format_arg(char* dest, fmt_data_t fmt_data, arg_t arg) { +constexpr inline void format_arg(char* dest, fmt_data_t fmt_data, arg_t arg) { +// constexpr auto error_array = get_init_array('f'); + detail::format_integral(dest, arg, fmt_data); }; - +// TODO: Error handling template -constexpr void format_arg(char* dest, fmt_data_t fmt_data, arg_t) { +constexpr inline void format_arg(char* dest, fmt_data_t fmt_data, arg_t) { *(dest) = 'f'; *(dest + fmt_data.length - fmt_data.precision - 1) = '.'; }; // TODO: Error handling -constexpr void format_arg(char* dest, fmt_data_t fmt_data, const char* arg) { +constexpr inline void format_arg(char* dest, fmt_data_t fmt_data, const char* arg) { const std::size_t len = const_strlen(arg); if (len > fmt_data.length) return; @@ -68,20 +70,21 @@ constexpr void format_arg(char* dest, fmt_data_t fmt_data, const char* arg) { }; +// End of recursion template -constexpr void format_args(char*) { +constexpr inline void format_args(char*) { } template -constexpr void format_args(char* dest, first_arg_t first_arg, args_t... args) { +constexpr inline void format_args(char* dest, first_arg_t first_arg, args_t... args) { format_arg(dest + fmt_data_array[0].position, fmt_data_array[0], first_arg); format_args(dest, args...); } template -consteval std::array()> get_preproc_string() { - auto result = get_zero_array()>(); +consteval inline std::array()> get_preproc_string() { + auto result = get_init_array()>('0'); int i = 0; @@ -107,7 +110,7 @@ consteval std::array()> get_preproc_string() { template -constexpr auto format(args_t... args) { +constexpr inline auto format(args_t... args) { constexpr auto ast = detail::parse_string().value; constexpr auto fmt_data = detail::get_fmt_data(); diff --git a/inc/format_impl.h b/inc/format_impl.h index 68f3de7..c1e4216 100644 --- a/inc/format_impl.h +++ b/inc/format_impl.h @@ -47,9 +47,6 @@ constexpr inline void copy2(char* dst, const char* src) { template constexpr inline void format_decimal(char* out, UInt value, int size) { - // TODO: Error handling (Maybe calculate "ffff..." as a constant expression - // and then set the out pointer with a branchless statement) - out += size; while (value >= 100) { out -= 2; diff --git a/inc/parse.h b/inc/parse.h index 6ca6af3..f1da473 100644 --- a/inc/parse.h +++ b/inc/parse.h @@ -48,7 +48,7 @@ namespace detail { template -constexpr unsigned count_braces() { +constexpr inline unsigned count_braces() { unsigned result = 0; for (unsigned i = 0; i < s.size(); ++i) { @@ -59,7 +59,7 @@ constexpr unsigned count_braces() { } template -constexpr unsigned strlen_braces() { +constexpr inline unsigned strlen_braces() { unsigned result = 0; bool brace_open = false; @@ -81,7 +81,7 @@ constexpr unsigned strlen_braces() { } template -constexpr int get_ast_len() { +constexpr inline int get_ast_len() { return (s.size() - strlen_braces() + count_braces()); } @@ -94,13 +94,13 @@ constexpr int get_ast_len() { template -constexpr bool is_digit(unsigned i) { +constexpr inline bool is_digit(unsigned i) { return (s[i] > 47) && (s[i] < 58); } template -constexpr parse_result_t parse_number(unsigned i) { +constexpr inline parse_result_t parse_number(unsigned i) { unsigned number = 0; if (!is_digit(i)) { @@ -117,7 +117,7 @@ constexpr parse_result_t parse_number(unsigned i) { } template -constexpr parse_result_t parse_type(unsigned i) { +constexpr inline parse_result_t parse_type(unsigned i) { switch (s[i]) { case 's': return {true, ++i, FormatType::s}; @@ -159,7 +159,7 @@ constexpr parse_result_t parse_type(unsigned i) { } template -constexpr parse_result_t parse_fmt_string(unsigned i) { +constexpr inline parse_result_t parse_fmt_string(unsigned i) { fmt_node_t result; if (s[i] == '0') { @@ -193,7 +193,7 @@ constexpr parse_result_t parse_fmt_string(unsigned i) { } template -constexpr parse_result_t parse_braces(unsigned i) { +constexpr inline parse_result_t parse_braces(unsigned i) { if (s[i] == '}') { ++i; return {true, i, {}}; @@ -214,7 +214,7 @@ constexpr parse_result_t parse_braces(unsigned i) { } template -constexpr parse_result_t()>> parse_string() { +constexpr inline parse_result_t()>> parse_string() { parse_result_t()>> result; result.is_valid = true; diff --git a/inc/utility.h b/inc/utility.h index 42a2697..86b2052 100644 --- a/inc/utility.h +++ b/inc/utility.h @@ -10,7 +10,7 @@ namespace detail { -constexpr std::size_t const_pow(std::size_t base, std::size_t pow) { +constexpr inline std::size_t const_pow(std::size_t base, std::size_t pow) { if (pow == 0) return 1; else @@ -18,34 +18,44 @@ constexpr std::size_t const_pow(std::size_t base, std::size_t pow) { } +//template +//constexpr std::array get_zero_array() { +// std::array result; +// +// for (auto& c : result) +// c = '0'; +// +// return result; +//} + template -constexpr std::array get_zero_array() { +constexpr inline std::array get_init_array(char val) { std::array result; for (auto& c : result) - c = '0'; + c = val; return result; } -template -constexpr std::array get_init_array() { - std::array result; - - if constexpr (fmt_node.has_zero_padding) { - for (auto& c : result) - c = '0'; - } else { - for (auto& c : result) - c = ' '; - } - - return result; -} +//template +//constexpr std::array get_init_array() { +// std::array result; +// +// if constexpr (fmt_node.has_zero_padding) { +// for (auto& c : result) +// c = '0'; +// } else { +// for (auto& c : result) +// c = ' '; +// } +// +// return result; +//} template -consteval std::size_t count_ast_format_nodes() { +consteval inline std::size_t count_ast_format_nodes() { std::size_t result = 0; for (const auto& node : ast) @@ -56,7 +66,7 @@ consteval std::size_t count_ast_format_nodes() { template -consteval std::array()> get_fmt_data() { +consteval inline std::array()> get_fmt_data() { std::array()> result = {}; std::size_t position = 0; @@ -84,7 +94,7 @@ consteval std::array()> get_fmt_data() { template -consteval std::array +consteval inline std::array drop_first(std::array array) { static_assert(t_n > 0, "Can't drop first element of array with no elements"); @@ -98,7 +108,7 @@ drop_first(std::array array) { template -consteval int get_ast_output_len() { +consteval inline int get_ast_output_len() { unsigned result = 0; for (const auto& ast_node : t_ast) { @@ -111,7 +121,7 @@ consteval int get_ast_output_len() { return result; } -constexpr std::size_t const_strlen(const char* arg) { +constexpr inline std::size_t const_strlen(const char* arg) { if (std::is_constant_evaluated()) { return *arg ? 1 + const_strlen(arg + 1) : 0; } else {