microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
debug_float.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
31#include <cstddef>
32#include <cstdio>
33#include <microfmt/microfmt.hpp>
34#include <type_traits>
35
36namespace reloco {
37
38namespace detail {
39
44// low-level formatting: raw character pointers and integer width conversions bounded by the buffer sizes checked here.
45RELOCO_BEGIN_UNSAFE_CODE
46template <typename T> inline void format_debug_float(T val, const sink &out) noexcept {
47 char buf[64] = {};
48 int written = {};
49 if constexpr (std::is_same_v<T, long double>) {
50 written = std::snprintf(buf, sizeof(buf), "%Lg", val);
51 } else {
52 written = std::snprintf(buf, sizeof(buf), "%g", static_cast<double>(val));
53 }
54 if (written <= 0) {
55 return;
56 }
57
58 const std::size_t len =
59 static_cast<std::size_t>(written) < sizeof(buf) ? static_cast<std::size_t>(written) : sizeof(buf) - 1;
60 const microfmt::string_view text(buf, len);
61 out.write(text);
62
63 const bool has_dot_or_exp = text.find('.') != microfmt::string_view::npos ||
64 text.find('e') != microfmt::string_view::npos ||
65 text.find('E') != microfmt::string_view::npos;
66 const bool is_special =
67 text.find("inf") != microfmt::string_view::npos || text.find("nan") != microfmt::string_view::npos;
68 if (!has_dot_or_exp && !is_special) {
69 out.write(".0");
70 }
71}
72RELOCO_END_UNSAFE_CODE
73
74} // namespace detail
75
77template <> struct Debug<float> {
78 static void format(float val, const sink &out) noexcept { detail::format_debug_float(val, out); }
79};
80
82template <> struct Debug<double> {
83 static void format(double val, const sink &out) noexcept { detail::format_debug_float(val, out); }
84};
85
87template <> struct Debug<long double> {
88 static void format(long double val, const sink &out) noexcept { detail::format_debug_float(val, out); }
89};
90
91} // namespace reloco
Core formatting primitives, sinks, and customization point.
RELOCO_BEGIN_UNSAFE_CODE void format_debug_float(T val, const sink &out) noexcept
Shared g/Lg-based implementation behind every Debug<float/double/long double>::format below.
Definition debug_float.hpp:46
Definition debug_float.hpp:36
static void format(double val, const sink &out) noexcept
Definition debug_float.hpp:83
static void format(float val, const sink &out) noexcept
Definition debug_float.hpp:78
static void format(long double val, const sink &out) noexcept
Definition debug_float.hpp:88