#pragma once #include class Console { public: virtual ~Console() = default; virtual void write(char c) = 0; virtual void write(ViewIterator& msg) = 0; virtual void update_cursor() = 0; static void set(Console* ptr); static Console* get(); }; template void print_c(Console* c, const T& a) { if constexpr (is_same()) { c->write(a); } else if constexpr (requires { StringView(a); }) { StringView v(a); auto iter = v.begin(); c->write(iter); } else if constexpr (requires { IntegerView(a); }) { IntegerView v(a); auto iter = v.begin(); c->write(iter); } else c->write(a); } template void print_c(Console* console, const T& a, const Args&... x) { print_c(console, a); print_c(console, x...); } template void printk(const T& a, const Args&... x) { if (auto* c = Console::get()) { print_c(c, a, x...); c->update_cursor(); } } extern "C" __attribute__((__noreturn__)) void abort();