10#include "../microfmt.hpp"
54 const size_t len = spec.size();
57 if (pos < len && (spec[pos] ==
'+' || spec[pos] ==
'-' || spec[pos] ==
' ')) {
58 if (spec[pos] !=
'-') {
65 if (pos < len && spec[pos] ==
'#') {
71 if (pos < len && spec[pos] ==
'.') {
74 while (pos < len && spec[pos] >=
'0' && spec[pos] <=
'9') {
75 res.precision = res.precision * 10 + (spec[pos++] -
'0');
81 const char ch = spec[pos];
82 if (ch ==
'f' || ch ==
'F' || ch ==
'e' || ch ==
'E' || ch ==
'g' || ch ==
'G' || ch ==
'a' || ch ==
'A') {
103 if (spec.sign !=
'\0') {
104 dest[idx++] = spec.sign;
109 if (spec.precision >= 0) {
114 if constexpr (std::is_same_v<T, long double>) {
118 dest[idx++] = spec.type;
135RELOCO_BEGIN_UNSAFE_CODE
138 const sink &out)
noexcept {
139 char fmt_buf[16] = {};
140 build_printf_float_format<T>(fmt_buf, spec);
143 const auto print_float = [&spec, &fmt_buf, &val](
char *dest,
size_t size)
noexcept {
144 if (spec.precision >= 0)
145 return std::snprintf(dest, size, fmt_buf, spec.precision, val);
146 return std::snprintf(dest, size, fmt_buf, val);
148 const int written = print_float(buf,
sizeof(buf));
151 if (
static_cast<size_t>(written) <
sizeof(buf)) {
152 out.write(microfmt::string_view(buf,
static_cast<size_t>(written)));
155 size_t heap_size =
static_cast<size_t>(written) + 1;
156 auto *heap_buf =
new (std::nothrow)
char[heap_size];
157 if (heap_buf !=
nullptr) {
158 (void)print_float(heap_buf, heap_size);
159 out.write(microfmt::string_view(heap_buf,
static_cast<size_t>(written)));
195 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
197 detail::format_float_via_printf<double>(
static_cast<double>(val), spec_, out);
199 RELOCO_END_UNSAFE_BUFFER_USAGE;
224 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
226 detail::format_float_via_printf<double>(val, spec_, out);
228 RELOCO_END_UNSAFE_BUFFER_USAGE;
253 void format(
long double val,
const sink &out)
const noexcept {
254 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
256 detail::format_float_via_printf<long double>(val, spec_, out);
258 RELOCO_END_UNSAFE_BUFFER_USAGE;
Definition microfmt.hpp:881
#define MICROFMT_API_CLASS
Definition compat.hpp:181
RELOCO_UNSAFE_BUFFER_USAGE size_t build_printf_float_format(char *dest, const parsed_float_spec &spec) noexcept
Builds a printf-style format string into a caller buffer.
Definition floating.hpp:99
constexpr parsed_float_spec parse_float_spec(microfmt::string_view spec) noexcept
Parses a floating-point format specifier string.
Definition floating.hpp:47
RELOCO_BEGIN_UNSAFE_CODE RELOCO_UNSAFE_BUFFER_USAGE void format_float_via_printf(T val, const parsed_float_spec &spec, const sink &out) noexcept
Formats a floating-point value via snprintf into the given sink.
Definition floating.hpp:137
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_END_UNSAFE_CODE
Definition remote_object.hpp:132
Parsed floating-point format specifier state.
Definition floating.hpp:23
char sign
Optional sign character: ‘’+',' 'or'\0'` (none).
Definition floating.hpp:27