libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
writer_float_runtime.hpp
1#pragma once
2
12constexpr bool Writer::UsesFloatTextBackend(FormatType type)
13{
14 switch (type)
15 {
16 case FormatType::FloatScientific:
17 case FormatType::DoubleScientific:
18 case FormatType::LongDoubleScientific:
19 case FormatType::FloatGeneral:
20 case FormatType::DoubleGeneral:
21 case FormatType::LongDoubleGeneral:
22 case FormatType::FloatFixed:
23 case FormatType::DoubleFixed:
24 case FormatType::LongDoubleFixed:
25 return true;
26 default:
27 return false;
28 }
29}
30
36constexpr bool Writer::FloatEnabled(FormatType type)
37{
38 switch (type)
39 {
40 case FormatType::FloatFixed:
41 return Config::enable_float_fixed;
42 case FormatType::FloatScientific:
43 return Config::enable_float_scientific;
44 case FormatType::FloatGeneral:
45 return Config::enable_float_general;
46 case FormatType::DoubleFixed:
47 return Config::enable_float_double && Config::enable_float_fixed;
48 case FormatType::DoubleScientific:
49 return Config::enable_float_double && Config::enable_float_scientific;
50 case FormatType::DoubleGeneral:
51 return Config::enable_float_double && Config::enable_float_general;
52 case FormatType::LongDoubleFixed:
53 return Config::enable_float_long_double && Config::enable_float_fixed;
54 case FormatType::LongDoubleScientific:
55 return Config::enable_float_long_double && Config::enable_float_scientific;
56 case FormatType::LongDoubleGeneral:
57 return Config::enable_float_long_double && Config::enable_float_general;
58 default:
59 return false;
60 }
61}
62
67constexpr uint8_t Writer::DefaultFloatPrecision()
68{
69 return Config::max_float_precision < 6 ? Config::max_float_precision : 6;
70}
71
79template <typename Float>
80bool Writer::ExceedsFixedIntegerDigits(Float value, uint8_t precision)
81{
82 if (!std::isfinite(value))
83 {
84 return false;
85 }
86
87 Float rounded =
88 value + static_cast<Float>(0.5L) * Power10<Float>(-static_cast<int>(precision));
89 if (rounded == 0)
90 {
91 return 1 > Config::max_float_integer_digits;
92 }
93
94 auto normalized = NormalizeDecimal(rounded);
95 size_t integer_digits =
96 (normalized.exponent >= 0) ? static_cast<size_t>(normalized.exponent) + 1U : 1U;
97 return integer_digits > Config::max_float_integer_digits;
98}
99
108inline bool Writer::AppendBufferChar(char* buffer, size_t capacity, size_t& size,
109 char ch)
110{
111 if (size >= capacity)
112 {
113 return false;
114 }
115 buffer[size++] = ch;
116 return true;
117}
118
127inline bool Writer::AppendBufferText(char* buffer, size_t capacity, size_t& size,
128 std::string_view text)
129{
130 if (text.size() > capacity - size)
131 {
132 return false;
133 }
134 std::memcpy(buffer + size, text.data(), text.size());
135 size += text.size();
136 return true;
137}
138
148inline bool Writer::AppendBufferU32ZeroPad(char* buffer, size_t capacity, size_t& size,
149 uint32_t value, uint8_t width)
150{
151 char digits[UnsignedDigitCapacity<uint32_t, 10>()];
152 size_t digit_count = AppendUnsigned<10>(digits, value);
153 size_t zero_count = (width > digit_count) ? static_cast<size_t>(width) - digit_count : 0;
154
155 for (size_t i = 0; i < zero_count; ++i)
156 {
157 if (!AppendBufferChar(buffer, capacity, size, '0'))
158 {
159 return false;
160 }
161 }
162
163 return AppendBufferText(buffer, capacity, size, std::string_view(digits, digit_count));
164}