microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
remote_layout_accessor.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
10#include "address_space.hpp"
11
12#include <cstddef>
13#include <limits>
14#include <type_traits>
15
16namespace microfmt {
17
18namespace detail {
19
20template <typename To, typename From>
21[[nodiscard]] constexpr bool convert_remote_layout_value(From value, To &out) noexcept {
22 if constexpr (std::is_same<To, From>::value) {
23 out = value;
24 return true;
25 } else {
26 static_assert(std::is_integral<To>::value && std::is_unsigned<To>::value,
27 "converted layout values must be unsigned integers");
28 static_assert(std::is_integral<From>::value && std::is_unsigned<From>::value,
29 "remote layout storage must be an unsigned integer");
30
31 if constexpr (sizeof(From) > sizeof(To)) {
32 if (value > static_cast<From>(std::numeric_limits<To>::max()))
33 return false;
34 }
35 out = static_cast<To>(value);
36 return true;
37 }
38}
39
40} // namespace detail
41
46template <typename Stored> struct remote_layout_offset {
47 ptrdiff_t offset;
48};
49
59template <typename Value, typename Callback> class remote_layout_accessor {
60public:
61 using value_type = Value;
62
63 static_assert(std::is_nothrow_copy_constructible<Callback>::value,
64 "remote layout callbacks must be nothrow copy-constructible");
65
66 constexpr explicit remote_layout_accessor(Callback callback) noexcept : callback_(callback) {}
67
68 template <typename... Inputs>
69 [[nodiscard]] bool read(address_space_ref space, uintptr_t object_address, Value &out,
70 Inputs... inputs) const noexcept {
71 static_assert(
72 std::is_nothrow_invocable_r<bool, const Callback &, address_space_ref, uintptr_t, Value &, Inputs...>::value,
73 "remote layout callback must be noexcept and return bool");
74 return callback_(space, object_address, out, inputs...);
75 }
76
77private:
78 Callback callback_;
79};
80
84template <typename Value, typename Stored> class remote_layout_accessor<Value, remote_layout_offset<Stored>> {
85public:
86 using value_type = Value;
87
88 constexpr explicit remote_layout_accessor(remote_layout_offset<Stored> source) noexcept : offset_(source.offset) {}
89
90 template <typename... Inputs>
91 [[nodiscard]] bool read(address_space_ref space, uintptr_t object_address, Value &out, Inputs...) const noexcept {
92 Stored stored{};
93 if (!space.read(detail::add_address_offset(object_address, offset_), stored))
94 return false;
95 return detail::convert_remote_layout_value(stored, out);
96 }
97
98private:
99 ptrdiff_t offset_;
100};
101
105template <typename Value, typename Source> class remote_layout_query {
106public:
107 constexpr explicit remote_layout_query(Source source) noexcept : accessor_(source) {}
108
109 template <typename... Inputs>
110 [[nodiscard]] bool operator()(address_space_ref space, uintptr_t object_address, Value &out,
111 Inputs... inputs) const noexcept {
112 return accessor_.read(space, object_address, out, inputs...);
113 }
114
115private:
117};
118
122template <typename Value, typename Callback>
123[[nodiscard]] constexpr auto make_remote_layout_query(Callback callback) noexcept {
125}
126
130template <typename Value, typename Stored = Value>
131[[nodiscard]] constexpr auto make_remote_offset_query(ptrdiff_t offset) noexcept {
132 using source_type = remote_layout_offset<Stored>;
133 return remote_layout_query<Value, source_type>(source_type{offset});
134}
135
136} // namespace microfmt
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
expected< void, address_space_error > read(uintptr_t addr, T &out_obj) const noexcept
Reads a trivially-copyable object from the remote address space.
Definition address_space.hpp:314
bool read(address_space_ref space, uintptr_t object_address, Value &out, Inputs...) const noexcept
Definition remote_layout_accessor.hpp:91
constexpr remote_layout_accessor(remote_layout_offset< Stored > source) noexcept
Definition remote_layout_accessor.hpp:88
Reads a remote layout property through a retained callback.
Definition remote_layout_accessor.hpp:59
Value value_type
Definition remote_layout_accessor.hpp:61
constexpr remote_layout_accessor(Callback callback) noexcept
Definition remote_layout_accessor.hpp:66
bool read(address_space_ref space, uintptr_t object_address, Value &out, Inputs... inputs) const noexcept
Definition remote_layout_accessor.hpp:69
Uniform query wrapper around callback and typed-offset accessors.
Definition remote_layout_accessor.hpp:105
constexpr remote_layout_query(Source source) noexcept
Definition remote_layout_accessor.hpp:107
bool operator()(address_space_ref space, uintptr_t object_address, Value &out, Inputs... inputs) const noexcept
Definition remote_layout_accessor.hpp:110
RELOCO_BEGIN_UNSAFE_CODE constexpr uintptr_t add_address_offset(uintptr_t address, ptrdiff_t offset) noexcept
Definition address_space.hpp:52
constexpr bool convert_remote_layout_value(From value, To &out) noexcept
Definition remote_layout_accessor.hpp:21
Definition assert.hpp:19
constexpr auto make_remote_offset_query(ptrdiff_t offset) noexcept
Creates a query backed by a typed remote-object offset.
Definition remote_layout_accessor.hpp:131
constexpr auto make_remote_layout_query(Callback callback) noexcept
Creates a query backed by a callback retained by value.
Definition remote_layout_accessor.hpp:123
Describes a property stored at a fixed offset in a remote object.
Definition remote_layout_accessor.hpp:46
ptrdiff_t offset
Definition remote_layout_accessor.hpp:47