BAN::Formatter now takes putc like function as a parameter

This allows us to use capturing lambdas as a putc like function
This commit is contained in:
Bananymous 2022-12-27 19:55:07 +02:00
parent 98fc72b0d0
commit fd4fdffd46
8 changed files with 80 additions and 77 deletions

View File

@ -71,12 +71,12 @@ private:
namespace BAN::Formatter
{
template<void(*PUTC_LIKE)(char)>
void print_argument_impl(const Error& error, const ValueFormat&)
template<typename F>
void print_argument_impl(F putc, const Error& error, const ValueFormat&)
{
if (error.GetErrorCode() == 0xFF)
print<PUTC_LIKE>(error.GetMessage());
print(putc, error.GetMessage());
else
print<PUTC_LIKE>("{} ({})", error.GetMessage(), error.GetErrorCode());
print(putc, "{} ({})", error.GetMessage(), error.GetErrorCode());
}
}

View File

@ -8,20 +8,20 @@ namespace BAN::Formatter
struct ValueFormat;
template<void(*PUTC_LIKE)(char)>
static void print(const char* format);
template<typename F>
static void print(F putc, const char* format);
template<void(*PUTC_LIKE)(char), typename Arg, typename... Args>
static void print(const char* format, const Arg& arg, const Args&... args);
template<typename F, typename Arg, typename... Args>
static void print(F putc, const char* format, const Arg& arg, const Args&... args);
template<void(*PUTC_LIKE)(char), typename... Args>
static void println(const char* format = "", const Args&... args);
template<typename F, typename... Args>
static void println(F putc, const char* format = "", const Args&... args);
template<void(*PUTC_LIKE)(char), typename T>
static size_t print_argument(const char* format, const T& arg);
template<typename F, typename T>
static size_t print_argument(F putc, const char* format, const T& arg);
template<void(*PUTC_LIKE)(char), typename T>
static void print_argument_impl(T value, const ValueFormat& format);
template<typename F, typename T>
static void print_argument_impl(F putc, T value, const ValueFormat& format);
/*
@ -38,43 +38,43 @@ namespace BAN::Formatter
bool upper = false;
};
template<void(*PUTC_LIKE)(char)>
void print(const char* format)
template<typename F>
void print(F putc, const char* format)
{
while (*format)
{
PUTC_LIKE(*format);
putc(*format);
format++;
}
}
template<void(*PUTC_LIKE)(char), typename Arg, typename... Args>
void print(const char* format, const Arg& arg, const Args&... args)
template<typename F, typename Arg, typename... Args>
void print(F putc, const char* format, const Arg& arg, const Args&... args)
{
while (*format && *format != '{')
{
PUTC_LIKE(*format);
putc(*format);
format++;
}
if (*format == '{')
{
size_t arg_len = print_argument<PUTC_LIKE>(format, arg);
size_t arg_len = print_argument(putc, format, arg);
if (arg_len == size_t(-1))
return print<PUTC_LIKE>(format);
print<PUTC_LIKE>(format + arg_len, args...);
return print(putc, format);
print(putc, format + arg_len, args...);
}
}
template<void(*PUTC_LIKE)(char), typename... Args>
void println(const char* format, const Args&... args)
template<typename F, typename... Args>
void println(F putc, const char* format, const Args&... args)
{
print<PUTC_LIKE>(format, args...);
PUTC_LIKE('\n');
print(putc, format, args...);
putc('\n');
}
template<void(*PUTC_LIKE)(char), typename Arg>
size_t print_argument(const char* format, const Arg& argument)
template<typename F, typename Arg>
size_t print_argument(F putc, const char* format, const Arg& argument)
{
ValueFormat value_format;
@ -131,7 +131,7 @@ namespace BAN::Formatter
if (format[i] != '}')
return size_t(-1);
print_argument_impl<PUTC_LIKE>(argument, value_format);
print_argument_impl(putc, argument, value_format);
return i + 1;
}
@ -149,13 +149,13 @@ namespace BAN::Formatter
return '?';
}
template<void(*PUTC_LIKE)(char), typename T>
void print_integer(T value, const ValueFormat& format)
template<typename F, typename T>
void print_integer(F putc, T value, const ValueFormat& format)
{
if (value == 0)
{
for (int i = 0; i < format.fill || i < 1; i++)
PUTC_LIKE('0');
putc('0');
return;
}
@ -186,21 +186,21 @@ namespace BAN::Formatter
if (sign)
*(--ptr) = '-';
print<PUTC_LIKE>(ptr);
print(putc, ptr);
}
template<void(*PUTC_LIKE)(char), typename T>
void print_floating(T value, const ValueFormat& format)
template<typename F, typename T>
void print_floating(F putc, T value, const ValueFormat& format)
{
int64_t int_part = (int64_t)value;
T frac_part = value - (T)int_part;
if (frac_part < 0)
frac_part = -frac_part;
print_integer<PUTC_LIKE>(int_part, format);
print_integer(putc, int_part, format);
if (format.percision > 0)
PUTC_LIKE('.');
putc('.');
for (int i = 0; i < format.percision; i++)
{
@ -208,17 +208,17 @@ namespace BAN::Formatter
if (i == format.percision - 1)
frac_part += 0.5;
PUTC_LIKE(value_to_base_char((uint8_t)frac_part % format.base, format.base, format.upper));
putc(value_to_base_char((uint8_t)frac_part % format.base, format.base, format.upper));
}
}
template<void(*PUTC_LIKE)(char)>
void print_pointer(void* ptr, const ValueFormat& format)
template<typename F>
void print_pointer(F putc, void* ptr, const ValueFormat& format)
{
uintptr_t value = (uintptr_t)ptr;
print<PUTC_LIKE>("0x");
print(putc, "0x");
for (int i = sizeof(void*) * 8 - 4; i >= 0; i -= 4)
PUTC_LIKE(value_to_base_char((value >> i) & 0xF, 16, format.upper));
putc(value_to_base_char((value >> i) & 0xF, 16, format.upper));
}
/*
@ -227,27 +227,27 @@ namespace BAN::Formatter
*/
template<void(*PUTC_LIKE)(char)> void print_argument_impl(short value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(int value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(long value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(long long value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<typename F> void print_argument_impl(F putc, short value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, int value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, long value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, long long value, const ValueFormat& format) { print_integer(putc, value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(unsigned short value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(unsigned int value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(unsigned long value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(unsigned long long value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<typename F> void print_argument_impl(F putc, unsigned short value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, unsigned int value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, unsigned long value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, unsigned long long value, const ValueFormat& format) { print_integer(putc, value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(float value, const ValueFormat& format) { print_floating<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(double value, const ValueFormat& format) { print_floating<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(long double value, const ValueFormat& format) { print_floating<PUTC_LIKE>(value, format); }
template<typename F> void print_argument_impl(F putc, float value, const ValueFormat& format) { print_floating(putc, value, format); }
template<typename F> void print_argument_impl(F putc, double value, const ValueFormat& format) { print_floating(putc, value, format); }
template<typename F> void print_argument_impl(F putc, long double value, const ValueFormat& format) { print_floating(putc, value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(char value, const ValueFormat&) { PUTC_LIKE(value); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(signed char value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(unsigned char value, const ValueFormat& format) { print_integer<PUTC_LIKE>(value, format); }
template<typename F> void print_argument_impl(F putc, char value, const ValueFormat&) { putc(value); }
template<typename F> void print_argument_impl(F putc, signed char value, const ValueFormat& format) { print_integer(putc, value, format); }
template<typename F> void print_argument_impl(F putc, unsigned char value, const ValueFormat& format) { print_integer(putc, value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(bool value, const ValueFormat& format) { print<PUTC_LIKE>(value ? "true" : "false"); }
template<typename F> void print_argument_impl(F putc, bool value, const ValueFormat& format) { print(putc, value ? "true" : "false"); }
template<void(*PUTC_LIKE)(char), typename T> void print_argument_impl(T* value, const ValueFormat& format) { print_pointer<PUTC_LIKE>((void*)value, format); }
template<void(*PUTC_LIKE)(char)> void print_argument_impl(const char* value, const ValueFormat&) { print<PUTC_LIKE>(value);}
template<typename F, typename T> void print_argument_impl(F putc, T* value, const ValueFormat& format) { print_pointer(putc, (void*)value, format); }
template<typename F> void print_argument_impl(F putc, const char* value, const ValueFormat&) { print(putc, value);}
}

View File

@ -68,10 +68,11 @@ namespace BAN
namespace BAN::Formatter
{
template<void(*PUTC_LIKE)(char)> void print_argument_impl(const String& string, const ValueFormat&)
template<typename F>
void print_argument_impl(F putc, const String& string, const ValueFormat&)
{
for (String::size_type i = 0; i < string.Size(); i++)
PUTC_LIKE(string[i]);
putc(string[i]);
}
}

View File

@ -44,10 +44,11 @@ namespace BAN
namespace BAN::Formatter
{
template<void(*PUTC_LIKE)(char)> void print_argument_impl(const StringView& sv, const ValueFormat&)
template<typename F>
void print_argument_impl(F putc, const StringView& sv, const ValueFormat&)
{
for (StringView::size_type i = 0; i < sv.Size(); i++)
PUTC_LIKE(sv[i]);
putc(sv[i]);
}
}

View File

@ -23,11 +23,12 @@ namespace BAN
namespace BAN::Formatter
{
template<void(*PUTC_LIKE)(char)> void print_argument_impl(const Time& time, const ValueFormat&)
template<typename F>
void print_argument_impl(F putc, const Time& time, const ValueFormat&)
{
constexpr const char* week_days[] { "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
constexpr const char* months[] { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
print<PUTC_LIKE>("{} {} {} {2}:{2}:{2} GMT+0 {4}", week_days[time.week_day], months[time.month], time.day, time.hour, time.minute, time.second, time.year);
print(putc, "{} {} {} {2}:{2}:{2} GMT+0 {4}", week_days[time.week_day], months[time.month], time.day, time.hour, time.minute, time.second, time.year);
}
}

View File

@ -5,22 +5,22 @@
#define dprintln(...) \
do { \
BAN::Formatter::print<Serial::serial_putc>("[{5.3}] {}({}): ", (float)PIT::ms_since_boot() / 1000.0f, __FILE__, __LINE__); \
BAN::Formatter::println<Serial::serial_putc>(__VA_ARGS__); \
BAN::Formatter::print(Serial::serial_putc, "[{5.3}] {}({}): ", (float)PIT::ms_since_boot() / 1000.0f, __FILE__, __LINE__); \
BAN::Formatter::println(Serial::serial_putc, __VA_ARGS__); \
} while(false)
#define dwarnln(...) \
do { \
BAN::Formatter::print<Serial::serial_putc>("\e[33m"); \
BAN::Formatter::print(Serial::serial_putc, "\e[33m"); \
dprintln(__VA_ARGS__); \
BAN::Formatter::print<Serial::serial_putc>("\e[m"); \
BAN::Formatter::print(Serial::serial_putc, "\e[m"); \
} while(false)
#define derrorln(...) \
do { \
BAN::Formatter::print<Serial::serial_putc>("\e[31m"); \
BAN::Formatter::print(Serial::serial_putc, "\e[31m"); \
dprintln(__VA_ARGS__); \
BAN::Formatter::print<Serial::serial_putc>("\e[m"); \
BAN::Formatter::print(Serial::serial_putc, "\e[m"); \
} while(false)
namespace Serial

View File

@ -3,5 +3,5 @@
#include <BAN/Formatter.h>
#include <kernel/TTY.h>
#define kprint(...) BAN::Formatter::print<TTY::PutCharCurrent>(__VA_ARGS__)
#define kprintln(...) BAN::Formatter::println<TTY::PutCharCurrent>(__VA_ARGS__)
#define kprint(...) BAN::Formatter::print(TTY::PutCharCurrent, __VA_ARGS__)
#define kprintln(...) BAN::Formatter::println(TTY::PutCharCurrent, __VA_ARGS__)

View File

@ -72,7 +72,7 @@ namespace Kernel
for (size_t i = 2; i < arguments.Size(); i++)
kprint(" {}", arguments[i]);
}
kprintln();
kprintln("");
return;
}
@ -125,7 +125,7 @@ namespace Kernel
if (edx & ((uint32_t)1 << i))
kprint("{}{}", first ? (first = false, "") : ", ", CPUID::FeatStringEDX((uint32_t)1 << i));
if (!first)
kprintln();
kprintln("");
return;
}