Added missing return in format_decimal(); Added first support for negative numbers
This commit is contained in:
parent
50024240ef
commit
0db75bbdd8
11
inc/format.h
11
inc/format.h
@ -40,21 +40,16 @@ constexpr inline void check_fmt_params() {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Error handling
|
|
||||||
template <fmt_data_t fmt_data, std::integral arg_t>
|
template <fmt_data_t fmt_data, std::integral arg_t>
|
||||||
constexpr inline void format_arg(char* dest, arg_t arg) {
|
constexpr inline void format_arg(char* dest, arg_t arg) {
|
||||||
constexpr auto error_array = get_init_array<fmt_data.length>('f');
|
|
||||||
|
|
||||||
detail::format_int(dest, arg, fmt_data);
|
detail::format_int(dest, arg, fmt_data);
|
||||||
};
|
};
|
||||||
// TODO: Error handling
|
|
||||||
template <fmt_data_t fmt_data, std::floating_point arg_t>
|
template <fmt_data_t fmt_data, std::floating_point arg_t>
|
||||||
constexpr inline void format_arg(char* dest, arg_t arg) {
|
constexpr inline void format_arg(char* dest, arg_t arg) {
|
||||||
*(dest) = 'f';
|
|
||||||
*(dest + fmt_data.length - fmt_data.precision - 1) = '.';
|
|
||||||
|
|
||||||
//detail::format_float(dest, arg, fmt_data);
|
//detail::format_float(dest, arg, fmt_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
template<fmt_data_t fmt_data>
|
template<fmt_data_t fmt_data>
|
||||||
constexpr inline void format_arg(char* dest, const char* arg) {
|
constexpr inline void format_arg(char* dest, const char* arg) {
|
||||||
@ -87,7 +82,7 @@ constexpr inline void format_args(char* dest, first_arg_t first_arg, args_t... a
|
|||||||
|
|
||||||
template <auto ast>
|
template <auto ast>
|
||||||
consteval inline std::array<char, get_ast_output_len<ast>()> get_preproc_string() {
|
consteval inline std::array<char, get_ast_output_len<ast>()> get_preproc_string() {
|
||||||
auto result = get_init_array<get_ast_output_len<ast>()>('0');
|
auto result = get_init_array<get_ast_output_len<ast>()>('f');
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
|||||||
@ -31,42 +31,6 @@ namespace detail {
|
|||||||
(factor)*1000000, (factor)*10000000, (factor)*100000000, \
|
(factor)*1000000, (factor)*10000000, (factor)*100000000, \
|
||||||
(factor)*1000000000
|
(factor)*1000000000
|
||||||
|
|
||||||
|
|
||||||
// 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<char>(*src++);
|
|
||||||
*dst = static_cast<char>(*src);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename uint_t>
|
|
||||||
constexpr inline void format_decimal(char* out, uint_t value, int size) {
|
|
||||||
out += size;
|
|
||||||
while (value >= 100) {
|
|
||||||
out -= 2;
|
|
||||||
copy2(out, digits2(static_cast<size_t>(value % 100)));
|
|
||||||
value /= 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value < 10) *--out = static_cast<char>('0' + value);
|
|
||||||
|
|
||||||
out -= 2;
|
|
||||||
copy2(out, digits2(static_cast<size_t>(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr int count_digits_fallback(T n) {
|
constexpr int count_digits_fallback(T n) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
@ -102,6 +66,47 @@ constexpr inline auto count_digits(uint64_t n) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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<char>(*src++);
|
||||||
|
*dst = static_cast<char>(*src);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename uint_t>
|
||||||
|
constexpr inline void format_decimal(char* out, uint_t value, int size) {
|
||||||
|
if (count_digits(value) > size) return;
|
||||||
|
|
||||||
|
out += size;
|
||||||
|
while (value >= 100) {
|
||||||
|
out -= 2;
|
||||||
|
copy2(out, digits2(static_cast<size_t>(value % 100)));
|
||||||
|
value /= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 10) {
|
||||||
|
*--out = static_cast<char>('0' + value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out -= 2;
|
||||||
|
copy2(out, digits2(static_cast<size_t>(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Integral types
|
* Integral types
|
||||||
@ -116,8 +121,14 @@ constexpr inline void format_int(char* out, uint_t value, fmt_data_t fmt_node) {
|
|||||||
|
|
||||||
template <std::signed_integral uint_t>
|
template <std::signed_integral uint_t>
|
||||||
constexpr inline void format_int(char* out, uint_t value, fmt_data_t fmt_node) {
|
constexpr inline void format_int(char* out, uint_t value, fmt_data_t fmt_node) {
|
||||||
if (value < 0) value = -value;
|
auto abs_value = static_cast<uint64_t>(value);
|
||||||
format_decimal(out, value, fmt_node.length);
|
const bool negative = value < 0;
|
||||||
|
|
||||||
|
if (negative) abs_value = 0 - abs_value;
|
||||||
|
format_decimal(out + 1 * (negative), abs_value,
|
||||||
|
fmt_node.length - 1 * (negative));
|
||||||
|
|
||||||
|
if (negative) *out = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -130,8 +141,10 @@ constexpr inline void format_int(char* out, uint_t value, fmt_data_t fmt_node) {
|
|||||||
|
|
||||||
template <std::floating_point float_t>
|
template <std::floating_point float_t>
|
||||||
constexpr inline void format_float(char* out, float_t value,
|
constexpr inline void format_float(char* out, float_t value,
|
||||||
fmt_data_t fmt_node) {
|
fmt_data_t fmt_data) {
|
||||||
// TODO
|
|
||||||
|
*(out) = 'f';
|
||||||
|
*(out + fmt_data.length - fmt_data.precision - 1) = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
auto formatted = "Test: {:12} {:012.5} {:8}"_fmt(argv[0], argc, -1234);
|
auto formatted = "Test: {:12} {:012.5} {:8}"_fmt(argv[0], 123.45, -1234567);
|
||||||
|
|
||||||
for (const auto& c : formatted)
|
for (const auto& c : formatted)
|
||||||
std::cout << c;
|
std::cout << c;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return formatted[6];
|
// return formatted[6];
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user