diff --git a/BAN/include/BAN/Errors.h b/BAN/include/BAN/Errors.h index 3f76dc78a..1af4cdbbe 100644 --- a/BAN/include/BAN/Errors.h +++ b/BAN/include/BAN/Errors.h @@ -115,7 +115,7 @@ namespace BAN namespace BAN::Formatter { template - void print_argument_impl(F putc, const Error& error, const ValueFormat&) + void print_argument(F putc, const Error& error, const ValueFormat&) { if (error.get_error_code() == 0xFF) print(putc, error.get_message()); diff --git a/BAN/include/BAN/Formatter.h b/BAN/include/BAN/Formatter.h index bab8314f2..3f7b7c4ee 100644 --- a/BAN/include/BAN/Formatter.h +++ b/BAN/include/BAN/Formatter.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -12,16 +14,19 @@ namespace BAN::Formatter static void print(F putc, const char* format); template - static void print(F putc, const char* format, const Arg& arg, const Args&... args); + static void print(F putc, const char* format, Arg&& arg, Args&&... args); template - static void println(F putc, const char* format = "", const Args&... args); + static void println(F putc, const char* format, Args&&... args); template - static size_t print_argument(F putc, const char* format, const T& arg); + static void print_argument(F putc, T value, const ValueFormat& format); - template - static void print_argument_impl(F putc, T value, const ValueFormat& format); + namespace detail + { + template + static size_t parse_format_and_print_argument(F putc, const char* format, T&& arg); + } /* @@ -49,7 +54,7 @@ namespace BAN::Formatter } template - void print(F putc, const char* format, const Arg& arg, const Args&... args) + void print(F putc, const char* format, Arg&& arg, Args&&... args) { while (*format && *format != '{') { @@ -59,166 +64,171 @@ namespace BAN::Formatter if (*format == '{') { - size_t arg_len = print_argument(putc, format, arg); + size_t arg_len = detail::parse_format_and_print_argument(putc, format, forward(arg)); if (arg_len == size_t(-1)) return print(putc, format); - print(putc, format + arg_len, args...); + print(putc, format + arg_len, forward(args)...); } } template - void println(F putc, const char* format, const Args&... args) + void println(F putc, const char* format, Args&&... args) { print(putc, format, args...); putc('\n'); } - template - size_t print_argument(F putc, const char* format, const Arg& argument) + namespace detail { - ValueFormat value_format; - if (format[0] != '{') - return size_t(-1); - - size_t i = 1; - do + template + size_t parse_format_and_print_argument(F putc, const char* format, Arg&& argument) { - if (!format[i] || format[i] == '}') - break; + ValueFormat value_format; - if ('0' <= format[i] && format[i] <= '9') + if (format[0] != '{') + return size_t(-1); + + size_t i = 1; + do { - int fill = 0; - while ('0' <= format[i] && format[i] <= '9') + if (!format[i] || format[i] == '}') + break; + + if ('0' <= format[i] && format[i] <= '9') { - fill = (fill * 10) + (format[i] - '0'); - i++; + int fill = 0; + while ('0' <= format[i] && format[i] <= '9') + { + fill = (fill * 10) + (format[i] - '0'); + i++; + } + value_format.fill = fill; } - value_format.fill = fill; - } - switch (format[i]) - { - case 'b': value_format.base = 2; value_format.upper = false; i++; break; - case 'B': value_format.base = 2; value_format.upper = true; i++; break; - case 'o': value_format.base = 8; value_format.upper = false; i++; break; - case 'O': value_format.base = 8; value_format.upper = true; i++; break; - case 'd': value_format.base = 10; value_format.upper = false; i++; break; - case 'D': value_format.base = 10; value_format.upper = true; i++; break; - case 'h': value_format.base = 16; value_format.upper = false; i++; break; - case 'H': value_format.base = 16; value_format.upper = true; i++; break; - default: break; - } - - if (!format[i] || format[i] == '}') - break; - - if (format[i] == '.') - { - i++; - int percision = 0; - while ('0' <= format[i] && format[i] <= '9') + switch (format[i]) { - percision = (percision * 10) + (format[i] - '0'); - i++; + case 'b': value_format.base = 2; value_format.upper = false; i++; break; + case 'B': value_format.base = 2; value_format.upper = true; i++; break; + case 'o': value_format.base = 8; value_format.upper = false; i++; break; + case 'O': value_format.base = 8; value_format.upper = true; i++; break; + case 'd': value_format.base = 10; value_format.upper = false; i++; break; + case 'D': value_format.base = 10; value_format.upper = true; i++; break; + case 'h': value_format.base = 16; value_format.upper = false; i++; break; + case 'H': value_format.base = 16; value_format.upper = true; i++; break; + default: break; } - value_format.percision = percision; - } - } while(false); + if (!format[i] || format[i] == '}') + break; - if (format[i] != '}') - return size_t(-1); + if (format[i] == '.') + { + i++; + int percision = 0; + while ('0' <= format[i] && format[i] <= '9') + { + percision = (percision * 10) + (format[i] - '0'); + i++; + } + value_format.percision = percision; + } - print_argument_impl(putc, argument, value_format); + } while(false); - return i + 1; - } + if (format[i] != '}') + return size_t(-1); - static char value_to_base_char(uint8_t value, int base, bool upper) - { - if (base <= 10) - return value + '0'; - if (base <= 36) + print_argument(putc, forward(argument), value_format); + + return i + 1; + } + + static char value_to_base_char(uint8_t value, int base, bool upper) { - if (value < 10) + if (base <= 10) return value + '0'; - return value + (upper ? 'A' : 'a') - 10; + if (base <= 36) + { + if (value < 10) + return value + '0'; + return value + (upper ? 'A' : 'a') - 10; + } + return '?'; } - return '?'; - } - template - void print_integer(F putc, T value, const ValueFormat& format) - { - if (value == 0) + template + void print_integer(F putc, T value, const ValueFormat& format) { - for (int i = 0; i < format.fill || i < 1; i++) - putc('0'); - return; + if (value == 0) + { + for (int i = 0; i < format.fill || i < 1; i++) + putc('0'); + return; + } + + bool sign = false; + + // Fits signed 64-bit binary number and null + char buffer[66]; + char* ptr = buffer + sizeof(buffer); + *(--ptr) = '\0'; + + if (value < 0) + { + sign = true; + T digit = (format.base - (value % format.base)) % format.base; + *(--ptr) = value_to_base_char(digit, format.base, format.upper); + value = -(value / format.base); + } + + while (value) + { + *(--ptr) = value_to_base_char(value % format.base, format.base, format.upper); + value /= format.base; + } + + while (ptr >= buffer + sizeof(buffer) - format.fill) + *(--ptr) = '0'; + + if (sign) + *(--ptr) = '-'; + + print(putc, ptr); } - bool sign = false; - - // Fits signed 64-bit binary number and null - char buffer[66]; - char* ptr = buffer + sizeof(buffer); - *(--ptr) = '\0'; - - if (value < 0) + template + void print_floating(F putc, T value, const ValueFormat& format) { - sign = true; - T digit = (format.base - (value % format.base)) % format.base; - *(--ptr) = value_to_base_char(digit, format.base, format.upper); - value = -(value / format.base); + 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, int_part, format); + + if (format.percision > 0) + putc('.'); + + for (int i = 0; i < format.percision; i++) + { + frac_part *= format.base; + if (i == format.percision - 1) + frac_part += 0.5; + + putc(value_to_base_char((uint8_t)frac_part % format.base, format.base, format.upper)); + } } - while (value) + template + void print_pointer(F putc, void* ptr, const ValueFormat& format) { - *(--ptr) = value_to_base_char(value % format.base, format.base, format.upper); - value /= format.base; + uintptr_t value = (uintptr_t)ptr; + print(putc, "0x"); + for (int i = sizeof(void*) * 8 - 4; i >= 0; i -= 4) + putc(value_to_base_char((value >> i) & 0xF, 16, format.upper)); } - while (ptr >= buffer + sizeof(buffer) - format.fill) - *(--ptr) = '0'; - - if (sign) - *(--ptr) = '-'; - - print(putc, ptr); - } - - template - 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, int_part, format); - - if (format.percision > 0) - putc('.'); - - for (int i = 0; i < format.percision; i++) - { - frac_part *= format.base; - if (i == format.percision - 1) - frac_part += 0.5; - - putc(value_to_base_char((uint8_t)frac_part % format.base, format.base, format.upper)); - } - } - - template - void print_pointer(F putc, void* ptr, const ValueFormat& format) - { - uintptr_t value = (uintptr_t)ptr; - print(putc, "0x"); - for (int i = sizeof(void*) * 8 - 4; i >= 0; i -= 4) - putc(value_to_base_char((value >> i) & 0xF, 16, format.upper)); } /* @@ -227,27 +237,16 @@ namespace BAN::Formatter */ - template void print_argument_impl(F putc, short value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, int value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, long value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, long long value, const ValueFormat& format) { print_integer(putc, value, format); } + template void print_argument(F putc, T value, const ValueFormat& format) { detail::print_integer(putc, value, format); } + template void print_argument(F putc, T value, const ValueFormat& format) { detail::print_floating(putc, value, format); } + template void print_argument(F putc, T value, const ValueFormat& format) { detail::print_pointer(putc, (void*)value, format); } - template void print_argument_impl(F putc, unsigned short value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, unsigned int value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, unsigned long value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, unsigned long long value, const ValueFormat& format) { print_integer(putc, value, format); } - - template void print_argument_impl(F putc, float value, const ValueFormat& format) { print_floating(putc, value, format); } - template void print_argument_impl(F putc, double value, const ValueFormat& format) { print_floating(putc, value, format); } - template void print_argument_impl(F putc, long double value, const ValueFormat& format) { print_floating(putc, value, format); } + template void print_argument(F putc, char value, const ValueFormat&) { putc(value); } + template void print_argument(F putc, bool value, const ValueFormat&) { print(putc, value ? "true" : "false"); } + template void print_argument(F putc, const char* value, const ValueFormat&) { print(putc, value);} - template void print_argument_impl(F putc, char value, const ValueFormat&) { putc(value); } - template void print_argument_impl(F putc, signed char value, const ValueFormat& format) { print_integer(putc, value, format); } - template void print_argument_impl(F putc, unsigned char value, const ValueFormat& format) { print_integer(putc, value, format); } - - template void print_argument_impl(F putc, bool value, const ValueFormat& format) { print(putc, value ? "true" : "false"); } - - template void print_argument_impl(F putc, T* value, const ValueFormat& format) { print_pointer(putc, (void*)value, format); } - template void print_argument_impl(F putc, const char* value, const ValueFormat&) { print(putc, value);} + //template void print_argument(F putc, signed char value, const ValueFormat& format) { detail::print_integer(putc, value, format); } + //template void print_argument(F putc, unsigned char value, const ValueFormat& format) { detail::print_integer(putc, value, format); } + //template void print_argument(F putc, T* value, const ValueFormat& format) { detail::print_pointer(putc, (void*)value, format); } } diff --git a/BAN/include/BAN/String.h b/BAN/include/BAN/String.h index 8747df360..0596a0461 100644 --- a/BAN/include/BAN/String.h +++ b/BAN/include/BAN/String.h @@ -82,7 +82,7 @@ namespace BAN::Formatter { template - void print_argument_impl(F putc, const String& string, const ValueFormat&) + void print_argument(F putc, const String& string, const ValueFormat&) { for (String::size_type i = 0; i < string.size(); i++) putc(string[i]); diff --git a/BAN/include/BAN/StringView.h b/BAN/include/BAN/StringView.h index acdcbbca6..bdd1973a8 100644 --- a/BAN/include/BAN/StringView.h +++ b/BAN/include/BAN/StringView.h @@ -50,7 +50,7 @@ namespace BAN::Formatter { template - void print_argument_impl(F putc, const StringView& sv, const ValueFormat&) + void print_argument(F putc, const StringView& sv, const ValueFormat&) { for (StringView::size_type i = 0; i < sv.size(); i++) putc(sv[i]); diff --git a/BAN/include/BAN/Time.h b/BAN/include/BAN/Time.h index 449870f20..6f2ed7b2d 100644 --- a/BAN/include/BAN/Time.h +++ b/BAN/include/BAN/Time.h @@ -24,7 +24,7 @@ namespace BAN::Formatter { template - void print_argument_impl(F putc, const Time& time, const ValueFormat&) + void print_argument(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" }; diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h index 69ca0877d..004ffe59c 100644 --- a/BAN/include/BAN/Vector.h +++ b/BAN/include/BAN/Vector.h @@ -418,13 +418,13 @@ namespace BAN::Formatter { template - void print_argument_impl(F putc, const Vector& vector, const ValueFormat& format) + void print_argument(F putc, const Vector& vector, const ValueFormat& format) { putc('['); for (typename Vector::size_type i = 0; i < vector.size(); i++) { if (i != 0) putc(','); - print_argument_impl(putc, vector[i], format); + print_argument(putc, vector[i], format); } putc(']'); } diff --git a/kernel/include/kernel/multiboot.h b/kernel/include/kernel/multiboot.h index 29df36d2d..2c42c8766 100644 --- a/kernel/include/kernel/multiboot.h +++ b/kernel/include/kernel/multiboot.h @@ -16,7 +16,7 @@ struct framebuffer_info_t uint8_t bpp; uint8_t type; uint8_t color_info[6]; -} __attribute__((packed)); +}; struct multiboot_memory_map_t { @@ -51,7 +51,7 @@ struct multiboot_info_t uint16_t vbe_interface_off; uint16_t vbe_interface_len; framebuffer_info_t framebuffer; -} __attribute__((packed)); +}; extern "C" multiboot_info_t* g_multiboot_info; extern "C" uint32_t g_multiboot_magic; diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 798409c51..b7ed4bf8a 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -54,6 +54,27 @@ ParsedCommandLine ParseCommandLine() return result; } +struct Test +{ + Test() { dprintln("construct (default)"); } + Test(const Test&) { dprintln("construct (copy)"); } + Test(Test&&) { dprintln("construct (move)"); } + ~Test() { dprintln("destruct"); } + Test& operator=(const Test&) { dprintln("assign (copy)"); return *this; } + Test& operator=(Test&&) { dprintln("assign (move)"); return *this; } +}; + +namespace BAN::Formatter +{ + + template + void print_argument(F putc, const Test& test, const ValueFormat& format) + { + print_argument(putc, &test, format); + } + +} + extern "C" void kernel_main() { using namespace Kernel;