#ifndef LOGGER_FORMAT_IMPL_H #define LOGGER_FORMAT_IMPL_H /* * * **************************************************************** * Disclaimer: Most of this code is shamelessly stolen from fmtlib * **************************************************************** * */ #include "utility.h" namespace detail { /* * * Utility functions * */ // Converts value in the range [0, 100) to a string. constexpr inline const char* digits2(size_t value) { // GCC generates slightly better code when value is pointer-size. return &"0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"[value * 2]; } constexpr inline void copy2(char* dst, const char* src) { if (!std::is_constant_evaluated()) { std::memcpy(dst, src, 2); return; } *dst++ = static_cast(*src++); *dst = static_cast(*src); } template constexpr inline void format_decimal(char* out, UInt value, int size) { out += size; while (value >= 100) { out -= 2; copy2(out, digits2(static_cast(value % 100))); value /= 100; } if (value < 10) *--out = static_cast('0' + value); out -= 2; copy2(out, digits2(static_cast(value))); } /* * * Integral types * */ template constexpr inline void format_integral(char* out, uint_t value, fmt_data_t fmt_node) { format_decimal(out, value, fmt_node.length); } template constexpr inline void format_integral(char* out, uint_t value, fmt_data_t fmt_node) { if (value < 0) value = -value; format_decimal(out, value, fmt_node.length); } /* * * Floating point types * */ template constexpr inline void format_floating_point(char* out, float_t value, fmt_data_t fmt_node) { // TODO } } // namespace detail #endif // LOGGER_FORMAT_IMPL_H