microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
binary.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
9#include "../microfmt.hpp"
10#include <cstddef>
11#include <cstdint>
12#include <type_traits>
13
14namespace microfmt {
15
16// ============================================================================
17// Binary View Configuration
18// ============================================================================
19
20template <typename T, typename = std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>>>
23 uint8_t min_bits{sizeof(T) * 8}; // Default to full bit-width (8, 16, 32, 64)
24 bool prefix{false}; // "0b" prefix
25 bool group_nibbles{false}; // '0010_1010' separator
26};
27
28// ============================================================================
29// Factory Helpers
30// ============================================================================
31
32// Fixed width matching type size (e.g., uint8_t -> 8 bits, uint16_t -> 16 bits)
33template <typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, int> = 0>
34[[nodiscard]] constexpr auto bin(T val) noexcept {
35 return binary_view<T>{val, static_cast<uint8_t>(sizeof(T) * 8), false, false};
36}
37
38// Explicit bit width: microfmt::bin<8>(val)
39template <uint8_t Bits, typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, int> = 0>
40[[nodiscard]] constexpr auto bin(T val) noexcept {
41 return binary_view<T>{val, Bits, false, false};
42}
43
44// With '0b' prefix and optional grouping
45template <typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, int> = 0>
46[[nodiscard]] constexpr auto bin_prefixed(T val, bool group_nibbles = false) noexcept {
47 return binary_view<T>{val, static_cast<uint8_t>(sizeof(T) * 8), true, group_nibbles};
48}
49
50// Grouped nibbles: 0010_1010
51template <typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, int> = 0>
52[[nodiscard]] constexpr auto bin_grouped(T val) noexcept {
53 return binary_view<T>{val, static_cast<uint8_t>(sizeof(T) * 8), false, true};
54}
55
56// ============================================================================
57// Formatter Specialization for binary_view
58// ============================================================================
59
60template <typename T> struct formatter<binary_view<T>> {
61 bool parse_prefix{false};
62 bool parse_grouped{false};
63 uint8_t parse_width{0};
64
65 constexpr void parse(format_parse_context &ctx) noexcept {
66 auto spec = ctx.spec();
67 for (char c : spec) {
68 if (c == '#')
69 parse_prefix = true;
70 if (c == '_')
71 parse_grouped = true;
72 }
73 }
74
75 void format(const binary_view<T> &bv, const sink &out) const noexcept {
76 const bool show_prefix = bv.prefix || parse_prefix;
77 const bool group = bv.group_nibbles || parse_grouped;
78
79 if (show_prefix) {
80 out.write("0b");
81 }
82
83 using UnsignedT = std::make_unsigned_t<T>;
84 const auto uval = static_cast<UnsignedT>(bv.value);
85
86 const uint8_t bits = (bv.min_bits > 0) ? bv.min_bits : static_cast<uint8_t>(sizeof(T) * 8);
87
88 for (int i = static_cast<int>(bits) - 1; i >= 0; --i) {
89 const char bit_char = ((uval >> i) & 1U) ? '1' : '0';
90 out.put(bit_char);
91
92 // Add '_' separator between 4-bit nibbles
93 if (group && (i % 4 == 0) && (i > 0)) {
94 out.put('_');
95 }
96 }
97 }
98};
99
100} // namespace microfmt
Definition microfmt.hpp:881
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition assert.hpp:19
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
constexpr bitfield_view bits(uint32_t raw_val, span< const bit_field > fields, bool show_raw_hex=true, microfmt::string_view sep=" | ") noexcept
Definition bitfield.hpp:36
constexpr auto bin_prefixed(T val, bool group_nibbles=false) noexcept
Definition binary.hpp:46
constexpr auto bin_grouped(T val, uint8_t group, char sep='_') noexcept
Definition base_views.hpp:49
constexpr auto bin(T val) noexcept
Definition binary.hpp:34
Definition binary.hpp:21
T value
Definition binary.hpp:22
constexpr void parse(format_parse_context &ctx) noexcept
Definition binary.hpp:65
void format(const binary_view< T > &bv, const sink &out) const noexcept
Definition binary.hpp:75
Definition microfmt.hpp:985