-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathformatter.hpp
More file actions
116 lines (110 loc) · 3.76 KB
/
formatter.hpp
File metadata and controls
116 lines (110 loc) · 3.76 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "stream.hpp"
#include "formatspecifier.hpp"
namespace hls
{
template <typename Integer, typename SinkImpl>
void integer_printer(Integer v, StreamSink<SinkImpl> &sink, const FormatSpecifier &fs, bool first)
{
switch (fs.get_integer_display_type())
{
case OCT_FORMAT:
{
if (first)
sink.receive_data(char32_t('0'));
std::make_unsigned_t<Integer> p = v;
if (p / 8)
integer_printer(p / 8, sink, fs, false);
sink.receive_data(char32_t('0') + (p % 8));
break;
}
case DEC_FORMAT:
if (first)
{
if (fs.has_sign())
{
if (fs.get_sign() == POS_SIGN)
{
if (v > 0)
sink.receive_data(char32_t('+'));
else
sink.receive_data(char32_t('-'));
}
else if (fs.get_sign() == SPC_SIGN)
{
if (v > 0)
sink.receive_data(char32_t(' '));
else
sink.receive_data(char32_t('-'));
}
else if (fs.get_sign() == NEG_SIGN)
{
if (v < 0)
sink.receive_data(char32_t('-'));
}
}
}
if (v / 10)
integer_printer(v / 10, sink, fs, false);
v = v < 0 ? -(v % 10) : (v % 10);
sink.receive_data(char32_t('0') + v);
break;
case HEX_FORMAT:
{
if (first)
{
sink.receive_data(char32_t('0'));
sink.receive_data(char32_t('x'));
}
// We don't care to the sign of the value, we just want the hex representation of it
std::make_unsigned_t<Integer> p = v;
if (p / 0x10)
integer_printer(p / 0x10, sink, fs, false);
if (p % 0x10 < 0xA)
sink.receive_data(char32_t('0') + p % 0x10);
else
sink.receive_data(char32_t('A') + (p % 0x10) - 0xA);
break;
}
default:
break;
}
}
template <typename T>
class Formatter
{
public:
template <typename SinkImpl>
static void value_to_sink(const T &v, StreamSink<SinkImpl> &sink, const FormatSpecifier &fs)
{
if constexpr (std::is_signed_v<T> || !std::is_signed_v<T>)
integer_printer(v, sink, fs, true);
else
[]<bool flag = false>() {
static_assert(flag, "Custom implementation needed for printing requested type.");
}();
}
};
template <>
class Formatter<const char *>
{
public:
template <typename SinkImpl>
static void value_to_sink(const char *str, StreamSink<SinkImpl> &sink, const FormatSpecifier &fs)
{
while (str && *str)
{
sink.receive_data((char32_t)(*str));
++str;
}
}
};
template <>
class Formatter<char *>
{
template <typename SinkImpl>
static void value_to_sink(char *str, StreamSink<SinkImpl> &sink, const FormatSpecifier &fs)
{
Formatter<const char *>::value_to_sink(str, sink, fs);
}
};
} // namespace hls