microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
bitfield.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 <cstdint>
11#include <string_view>
12
13namespace microfmt {
14
15enum class bit_type : uint8_t {
16 flag, // Single bit or multi-bit exact match (prints name when set)
17 value_hex, // Multi-bit field (prints NAME=0xVAL)
18 value_dec // Multi-bit field (prints NAME=VAL)
19};
20
21struct MICROFMT_API_CLASS RELOCO_POINTER bit_field {
22 uint32_t mask{};
23 uint8_t shift{0};
24 microfmt::string_view name{};
25 bit_type type{bit_type::flag};
26};
27
28struct MICROFMT_API_CLASS RELOCO_POINTER bitfield_view {
29 uint32_t raw_value{0};
30 span<const bit_field> fields{};
31 microfmt::string_view separator{" | "};
32 bool show_raw_hex{true};
33};
34
35// Convenience helper to construct a bitfield_view
36[[nodiscard]] constexpr bitfield_view bits(uint32_t raw_val, span<const bit_field> fields, bool show_raw_hex = true,
37 microfmt::string_view sep = " | ") noexcept {
38 return bitfield_view{raw_val, fields, sep, show_raw_hex};
39}
40
41template <> struct formatter<bitfield_view> {
42 constexpr void parse(format_parse_context &ctx) noexcept { (void)ctx; }
43
44 MICROFMT_API void format(const bitfield_view &bv, const sink &out) const noexcept;
45};
46
47#if MICROFMT_SHARED_PROVIDE_DEFINITIONS
48#include "bitfield.ipp"
49#endif
50
51// ============================================================================
52// Single Field Descriptor Helpers
53// ============================================================================
54
55// 1-bit boolean flag at bit position 'pos'
56#define MICROFMT_BIT_FLAG(pos, name) \
57 ::microfmt::bit_field { (1u << (pos)), static_cast<uint8_t>(pos), (name), ::microfmt::bit_type::flag }
58
59// Multi-bit masked integer field (mask, shift, name)
60#define MICROFMT_BIT_VALUE_DEC(mask, shift, name) \
61 ::microfmt::bit_field { (mask), static_cast<uint8_t>(shift), (name), ::microfmt::bit_type::value_dec }
62
63#define MICROFMT_BIT_VALUE_HEX(mask, shift, name) \
64 ::microfmt::bit_field { (mask), static_cast<uint8_t>(shift), (name), ::microfmt::bit_type::value_hex }
65
66// ============================================================================
67// Register Type Synthesis Macro
68// ============================================================================
69
70#define MICROFMT_DEFINE_REGISTER_TYPE(TypeName, UnderlyingType, ...) \
71 struct TypeName { \
72 UnderlyingType value{0}; \
73 \
74 constexpr TypeName() noexcept = default; \
75 constexpr TypeName(UnderlyingType v) noexcept : value(v) {} \
76 constexpr explicit operator UnderlyingType() const noexcept { return value; } \
77 \
78 static constexpr ::microfmt::bit_field fields[] = {__VA_ARGS__}; \
79 }; \
80 \
81 template <> struct microfmt::formatter<TypeName> { \
82 constexpr void parse(::microfmt::format_parse_context &) noexcept {} \
83 void format(const TypeName &reg, const ::microfmt::sink &out) const noexcept { \
84 ::microfmt::formatter<::microfmt::bitfield_view> f; \
85 f.format(::microfmt::bits(static_cast<uint32_t>(reg.value), ::microfmt::span(TypeName::fields)), out); \
86 } \
87 };
88
89} // namespace microfmt
Definition microfmt.hpp:881
#define MICROFMT_API_CLASS
Definition compat.hpp:181
#define MICROFMT_API
Definition compat.hpp:135
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
bit_type
Definition bitfield.hpp:15
Definition bitfield.hpp:21
Definition bitfield.hpp:28
constexpr void parse(format_parse_context &ctx) noexcept
Definition bitfield.hpp:42
MICROFMT_API void format(const bitfield_view &bv, const sink &out) const noexcept
Definition microfmt.hpp:985