microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
boost_monad.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 <boost/optional.hpp>
11#include <boost/outcome/result.hpp>
12#include <boost/variant2/variant.hpp>
13#include <type_traits>
14
15namespace microfmt {
16
17template <typename T> struct formatter<boost::optional<T>> {
18 microfmt::string_view forwarded_spec{};
19
20 constexpr void parse(format_parse_context &ctx) noexcept { forwarded_spec = ctx.spec(); }
21
22 void format(const boost::optional<T> &value, const sink &out) const noexcept {
23 if (!value) {
24 out.write("None");
25 return;
26 }
27
28 out.write("Some(");
29 formatter<T> inner;
30 format_parse_context inner_context(forwarded_spec);
31 inner.parse(inner_context);
32 inner.format(*value, out);
33 out.put(')');
34 }
35};
36
37template <typename... Ts> struct formatter<boost::variant2::variant<Ts...>> {
38 microfmt::string_view forwarded_spec{};
39 bool show_index{false};
40
41 constexpr void parse(format_parse_context &ctx) noexcept {
42 auto spec = ctx.spec();
43 if (!spec.empty() && (spec.front() == 'i' || spec.front() == '#')) {
44 show_index = true;
45 spec.remove_prefix(1);
46 }
47 forwarded_spec = spec;
48 }
49
50 void format(const boost::variant2::variant<Ts...> &value, const sink &out) const noexcept {
51 if (show_index) {
52 microfmt::format_to(out, "variant[{}](", value.index());
53 }
54
55 boost::variant2::visit(
56 [this, &out](const auto &active) noexcept {
57 using active_type = std::decay_t<decltype(active)>;
59 format_parse_context inner_context(forwarded_spec);
60 inner.parse(inner_context);
61 inner.format(active, out);
62 },
63 value);
64
65 if (show_index) {
66 out.put(')');
67 }
68 }
69};
70
71template <typename R, typename S, typename NoValuePolicy>
72struct formatter<boost::outcome_v2::basic_result<R, S, NoValuePolicy>> {
73 microfmt::string_view forwarded_spec{};
74
75 constexpr void parse(format_parse_context &ctx) noexcept { forwarded_spec = ctx.spec(); }
76
77 void format(const boost::outcome_v2::basic_result<R, S, NoValuePolicy> &result, const sink &out) const noexcept {
78 if (result.has_value()) {
79 out.write("Ok(");
80 if constexpr (!std::is_void_v<R>) {
81 formatter<R> inner;
82 format_parse_context inner_context(forwarded_spec);
83 inner.parse(inner_context);
84 inner.format(result.assume_value(), out);
85 }
86 out.put(')');
87 return;
88 }
89
90 if (result.has_error()) {
91 out.write("Err(");
92 formatter<S> inner;
93 format_parse_context inner_context(forwarded_spec);
94 inner.parse(inner_context);
95 inner.format(result.assume_error(), out);
96 out.put(')');
97 return;
98 }
99
100 out.write("NoValue");
101 }
102};
103
104} // namespace microfmt
Definition microfmt.hpp:881
Definition assert.hpp:19
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
void format(const boost::optional< T > &value, const sink &out) const noexcept
Definition boost_monad.hpp:22
constexpr void parse(format_parse_context &ctx) noexcept
Definition boost_monad.hpp:20
constexpr void parse(format_parse_context &ctx) noexcept
Definition boost_monad.hpp:75
void format(const boost::outcome_v2::basic_result< R, S, NoValuePolicy > &result, const sink &out) const noexcept
Definition boost_monad.hpp:77
constexpr void parse(format_parse_context &ctx) noexcept
Definition boost_monad.hpp:41
void format(const boost::variant2::variant< Ts... > &value, const sink &out) const noexcept
Definition boost_monad.hpp:50
Definition microfmt.hpp:985