1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#pragma once
#include <string.h>
template <typename T, bool reverse = false>
class Iterator {
public:
T next() { return buffer[reverse ? pos-- : pos++]; }
operator bool() const { return reverse ? (pos >= 0) : (pos < length); }
explicit Iterator(T* b, size_t l) : buffer(b), length(l) {
if (reverse)
pos = length - 1;
};
private:
ssize_t pos = 0;
T* const buffer;
const size_t length;
};
class Console {
public:
virtual void write(char c) = 0;
virtual void write(ViewIterator& msg) = 0;
virtual void update_cursor() = 0;
static void set(Console* ptr);
static Iterator<Console*> begin();
};
template <typename T>
void print_c(Console* c, const T& a) {
if constexpr (is_same<T, char>()) {
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 <typename T, typename... Args>
void print_c(Console* console, const T& a, const Args&... x) {
print_c(console, a);
print_c(console, x...);
}
template <typename T, typename... Args>
void printk(const T& a, const Args&... x) {
auto iter = Console::begin();
while (iter) {
auto* c = iter.next();
print_c(c, a, x...);
c->update_cursor();
}
}
extern "C" __attribute__((__noreturn__)) void abort();
|