microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
remote_container.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// ============================================================================
6// General Type-Erased Remote Container View & Context Builder Pattern
7// ============================================================================
8
9#pragma once
10
14#include "address_space.hpp"
15#include <cstddef>
16#include <cstdint>
17
18namespace microfmt {
19
20class remote_container_view;
21
27 bool print_key{true};
29 bool print_value{true};
31 microfmt::string_view kv_separator{": "};
33 microfmt::string_view entry_separator{", "};
35 microfmt::string_view open_bracket{"{"};
37 microfmt::string_view close_bracket{"}"};
39 size_t max_print{64};
40};
41
52template <typename IteratorState, typename FormatterFn> class RELOCO_OWNER container_context {
53public:
59 constexpr container_context(IteratorState initial_state, FormatterFn formatter) noexcept
60 : state_(initial_state), formatter_fn_(formatter) {}
61
71 static bool format_thunk(void *raw_ctx, address_space_ref space, span<std::byte> scratch, const sink &out,
72 const container_options &opts) noexcept {
73 auto *self = static_cast<container_context *>(raw_ctx);
74 return self->formatter_fn_(self->state_, opts, space, scratch, out);
75 }
76
81 [[nodiscard]] constexpr IteratorState &state() & noexcept RELOCO_LIFETIMEBOUND { return state_; }
86 [[nodiscard]] constexpr const IteratorState &state() const & noexcept RELOCO_LIFETIMEBOUND { return state_; }
87
88 [[nodiscard]] constexpr const IteratorState &state() const && = delete;
89
90private:
91 IteratorState state_;
92 FormatterFn formatter_fn_;
93};
94
102template <typename Tag, typename Dispatcher> class RELOCO_OWNER basic_remote_container {
103public:
104 using traits_type = typename Dispatcher::traits_type;
105 using context_type = typename traits_type::context_type;
106
107 constexpr basic_remote_container(uintptr_t container_addr, context_type context) noexcept
108 : container_addr_(container_addr), context_(std::move(context)) {}
109
110 [[nodiscard]] constexpr uintptr_t container_address() const noexcept { return container_addr_; }
111
112 [[nodiscard]] constexpr value_ref<context_type> context() & noexcept RELOCO_LIFETIMEBOUND {
113 return value_ref<context_type>(context_);
114 }
115
116 [[nodiscard]] constexpr value_ref<const context_type> context() const & noexcept RELOCO_LIFETIMEBOUND {
117 return value_ref<const context_type>(context_);
118 }
119
120 value_ref<context_type> context() && = delete;
121 value_ref<const context_type> context() const && = delete;
122
123 [[nodiscard]] constexpr remote_container_view view(address_space_ref space,
124 span<std::byte> scratch RELOCO_LIFETIMEBOUND,
125 container_options options = {}) & noexcept RELOCO_LIFETIMEBOUND;
126
128
129 static bool format_thunk(void *raw_ctx, address_space_ref space, span<std::byte> scratch, const sink &out,
130 const container_options &opts) noexcept {
131 auto &self = *static_cast<basic_remote_container *>(raw_ctx);
132 return Dispatcher::format(value_ref<const context_type>(self.context_), self.container_addr_, opts, space, scratch,
133 out);
134 }
135
136private:
137 uintptr_t container_addr_;
138 context_type context_;
139};
140
150template <typename IteratorState, typename FormatterFn>
151[[nodiscard]] constexpr auto make_container_context(IteratorState initial_state, FormatterFn formatter) noexcept {
153}
154
160public:
164 using format_fn_t = bool (*)(void *ctx, address_space_ref space, span<std::byte> scratch, const sink &out,
165 const container_options &opts) noexcept;
166
170 constexpr remote_container_view() noexcept = default;
171
181 template <typename Context>
182 constexpr remote_container_view(uintptr_t container_addr, address_space_ref space,
183 span<std::byte> scratch RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS,
184 value_ref<Context> ctx RELOCO_LIFETIME_CAPTURE_BY_THIS,
185 container_options options = {}) noexcept
186 : container_addr_(container_addr), space_(space), scratch_(scratch), ctx_(ctx.pointer()),
187 format_fn_(&Context::format_thunk), options_(options) {}
188
193 [[nodiscard]] constexpr uintptr_t container_address() const noexcept { return container_addr_; }
198 [[nodiscard]] constexpr address_space_ref space() const noexcept { return space_; }
203 [[nodiscard]] constexpr span<std::byte> scratch() const noexcept RELOCO_LIFETIMEBOUND { return scratch_; }
208 [[nodiscard]] constexpr const container_options &options() const & noexcept RELOCO_LIFETIMEBOUND { return options_; }
209 const container_options &options() const && = delete;
214 [[nodiscard]] constexpr bool is_null() const noexcept { return container_addr_ == 0 || !ctx_; }
215
222 bool format(const sink &out) const noexcept {
223 if (format_fn_ == nullptr || !ctx_)
224 return false;
225 return format_fn_(ctx_.get(), space_, scratch_, out, options_);
226 }
227
232 [[nodiscard]] constexpr explicit operator bool() const noexcept { return !is_null(); }
233
234private:
235 uintptr_t container_addr_{0};
236 address_space_ref space_{};
237 span<std::byte> scratch_{};
238 value_ptr<void> ctx_{};
239 format_fn_t format_fn_{nullptr};
240 container_options options_;
241};
242
243template <typename Tag, typename Dispatcher>
244[[nodiscard]] constexpr remote_container_view
246 container_options options) & noexcept {
247 return remote_container_view(container_addr_, space, scratch, value_ref<basic_remote_container>(*this), options);
248}
249
250} // namespace microfmt
251
252// ============================================================================
253// Formatter for remote_container_view
254// ============================================================================
255
257 constexpr void parse(microfmt::format_parse_context &) noexcept {}
258
259 void format(const microfmt::remote_container_view &view, const microfmt::sink &out) const noexcept {
260 if (view.is_null()) {
261 out.write("<null>");
262 return;
263 }
264 if (!view.format(out)) {
265 out.write("<fault>");
266 }
267 }
268};
Type-erased remote address-space access and remote string/object views.
Type-erased, two-word handle to a remote address space.
Definition address_space.hpp:204
Owning typed container bound to a compile-time traits dispatcher.
Definition remote_container.hpp:102
typename traits_type::context_type context_type
Definition remote_container.hpp:105
value_ref< context_type > context() &&=delete
remote_container_view view(address_space_ref, span< std::byte >, container_options={}) &&=delete
constexpr basic_remote_container(uintptr_t container_addr, context_type context) noexcept
Definition remote_container.hpp:107
constexpr value_ref< const context_type > context() const &noexcept RELOCO_LIFETIMEBOUND
Definition remote_container.hpp:116
constexpr uintptr_t container_address() const noexcept
Definition remote_container.hpp:110
constexpr value_ref< context_type > context() &noexcept RELOCO_LIFETIMEBOUND
Definition remote_container.hpp:112
value_ref< const context_type > context() const &&=delete
static bool format_thunk(void *raw_ctx, address_space_ref space, span< std::byte > scratch, const sink &out, const container_options &opts) noexcept
Definition remote_container.hpp:129
typename Dispatcher::traits_type traits_type
Definition remote_container.hpp:104
External context holder capturing container state and traversal/formatting logic.
Definition remote_container.hpp:52
static bool format_thunk(void *raw_ctx, address_space_ref space, span< std::byte > scratch, const sink &out, const container_options &opts) noexcept
Invokes the stored formatter through the type-erased view API.
Definition remote_container.hpp:71
constexpr container_context(IteratorState initial_state, FormatterFn formatter) noexcept
Stores container traversal state and its formatting callback.
Definition remote_container.hpp:59
constexpr const IteratorState & state() const &noexcept RELOCO_LIFETIMEBOUND
Returns the traversal state.
Definition remote_container.hpp:86
constexpr const IteratorState & state() const &&=delete
constexpr IteratorState & state() &noexcept RELOCO_LIFETIMEBOUND
Returns the mutable traversal state.
Definition remote_container.hpp:81
Definition microfmt.hpp:881
General type-erased view over any remote container or data structure. Manages its own formatting opti...
Definition remote_container.hpp:159
constexpr span< std::byte > scratch() const noexcept RELOCO_LIFETIMEBOUND
Returns the reusable scratch storage.
Definition remote_container.hpp:203
constexpr address_space_ref space() const noexcept
Returns the address space.
Definition remote_container.hpp:198
constexpr uintptr_t container_address() const noexcept
Returns the remote container address.
Definition remote_container.hpp:193
constexpr remote_container_view() noexcept=default
Constructs an empty, invalid view.
bool(*)(void *ctx, address_space_ref space, span< std::byte > scratch, const sink &out, const container_options &opts) noexcept format_fn_t
Type-erased function signature used to format a container.
Definition remote_container.hpp:165
bool format(const sink &out) const noexcept
Formats the remote container through its bound context.
Definition remote_container.hpp:222
constexpr const container_options & options() const &noexcept RELOCO_LIFETIMEBOUND
Returns the rendering configuration.
Definition remote_container.hpp:208
const container_options & options() const &&=delete
#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
void(*)(const void *val_ptr, microfmt::string_view spec, const sink &out) noexcept format_fn_t
Definition microfmt.hpp:1348
constexpr auto make_container_context(IteratorState initial_state, FormatterFn formatter) noexcept
Creates an external context for a remote container view.
Definition remote_container.hpp:151
Configuration options for formatting container views.
Definition remote_container.hpp:25
constexpr void parse(microfmt::format_parse_context &) noexcept
Definition remote_container.hpp:257
void format(const microfmt::remote_container_view &view, const microfmt::sink &out) const noexcept
Definition remote_container.hpp:259
Definition microfmt.hpp:985