nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
std_compat.hpp
Go to the documentation of this file.
1// nros-cpp: Optional std mode conveniences
2// Requires hosted C++ with STL — guarded by NROS_CPP_STD
3//
4// Provides:
5// A) std::function<void()> callback wrappers for Timer and GuardCondition
6// B) std::string forwarding overloads for name parameters
7// C) std::chrono::milliseconds overloads for spin/timer durations
8
16#ifndef NROS_CPP_STD_COMPAT_HPP
17#define NROS_CPP_STD_COMPAT_HPP
18
19// This header is a no-op without NROS_CPP_STD (allows freestanding syntax checks to pass).
20#ifdef NROS_CPP_STD
21
22#include <chrono>
23#include <functional>
24#include <memory>
25#include <string>
26
27namespace nros {
28
29// ============================================================================
30// A) std::function callback wrappers for Timer and GuardCondition
31// ============================================================================
32//
33// Lifetime: the heap-allocated std::function is owned by the Timer /
34// GuardCondition instance via `attach_std_closure(unique_ptr)`. The
35// runtime receives a raw pointer into the same std::function; the
36// Timer's destructor cancels the runtime callback before the
37// unique_ptr is dropped, so the raw pointer is never dereferenced
38// after free.
39
40namespace detail {
41
43inline void std_function_trampoline(void* context) {
44 auto* fn = static_cast<std::function<void()>*>(context);
45 (*fn)();
46}
47
48} // namespace detail
49
61inline Result create_timer(Node& node, Timer& out, std::chrono::milliseconds period,
62 std::function<void()> callback) {
63 auto fn =
64 std::unique_ptr<std::function<void()>>(new std::function<void()>(std::move(callback)));
65 auto* raw = fn.get();
66 Result r = node.create_timer(out, static_cast<uint64_t>(period.count()),
67 detail::std_function_trampoline, raw);
68 if (r.ok()) {
69 out.attach_std_closure(std::move(fn));
70 }
71 return r;
72}
73
78inline Result create_timer_oneshot(Node& node, Timer& out, std::chrono::milliseconds delay,
79 std::function<void()> callback) {
80 auto fn =
81 std::unique_ptr<std::function<void()>>(new std::function<void()>(std::move(callback)));
82 auto* raw = fn.get();
83 Result r = node.create_timer_oneshot(out, static_cast<uint64_t>(delay.count()),
84 detail::std_function_trampoline, raw);
85 if (r.ok()) {
86 out.attach_std_closure(std::move(fn));
87 }
88 return r;
89}
90
94inline Result create_guard_condition(Node& node, GuardCondition& out,
95 std::function<void()> callback) {
96 auto fn =
97 std::unique_ptr<std::function<void()>>(new std::function<void()>(std::move(callback)));
98 auto* raw = fn.get();
99 Result r = node.create_guard_condition(out, detail::std_function_trampoline, raw);
100 if (r.ok()) {
101 out.attach_std_closure(std::move(fn));
102 }
103 return r;
104}
105
106// ============================================================================
107// B) std::string forwarding overloads
108// ============================================================================
109
111inline Result init(const std::string& locator, uint8_t domain_id = 0) {
112 return init(locator.c_str(), domain_id);
113}
114
116inline Result create_node(Node& out, const std::string& name,
117 const std::string& ns = std::string()) {
118 return create_node(out, name.c_str(), ns.empty() ? nullptr : ns.c_str());
119}
120
121// -- Node member std::string overloads (free functions that forward) --
122
124template <typename M>
125Result create_publisher(Node& node, Publisher<M>& out, const std::string& topic,
126 const QoS& qos = QoS::default_profile()) {
127 return node.create_publisher(out, topic.c_str(), qos);
128}
129
131template <typename M>
132Result create_subscription(Node& node, Subscription<M>& out, const std::string& topic,
133 const QoS& qos = QoS::default_profile()) {
134 return node.create_subscription(out, topic.c_str(), qos);
135}
136
138template <typename S>
139Result create_service(Node& node, Service<S>& out, const std::string& service_name,
140 const QoS& qos = QoS::services()) {
141 return node.create_service(out, service_name.c_str(), qos);
142}
143
145template <typename S>
146Result create_client(Node& node, Client<S>& out, const std::string& service_name,
147 const QoS& qos = QoS::services()) {
148 return node.create_client(out, service_name.c_str(), qos);
149}
150
152template <typename A>
153Result create_action_server(Node& node, ActionServer<A>& out, const std::string& action_name,
154 const QoS& qos = QoS::services()) {
155 return node.create_action_server(out, action_name.c_str(), qos);
156}
157
159template <typename A>
160Result create_action_client(Node& node, ActionClient<A>& out, const std::string& action_name,
161 const QoS& qos = QoS::services()) {
162 return node.create_action_client(out, action_name.c_str(), qos);
163}
164
165// -- Executor std::string overloads --
166
168inline Result create_executor(Executor& out, const std::string& locator, uint8_t domain_id = 0) {
169 return Executor::create(out, locator.c_str(), domain_id);
170}
171
173inline Result create_node(Executor& exec, Node& out, const std::string& name,
174 const std::string& ns = std::string()) {
175 return exec.create_node(out, name.c_str(), ns.empty() ? nullptr : ns.c_str());
176}
177
178// ============================================================================
179// C) std::chrono duration overloads
180// ============================================================================
181
183inline Result spin_once(std::chrono::milliseconds timeout) {
184 return spin_once(static_cast<int32_t>(timeout.count()));
185}
186
188inline Result spin(std::chrono::milliseconds duration,
189 std::chrono::milliseconds poll = std::chrono::milliseconds(10)) {
190 return spin(static_cast<uint32_t>(duration.count()), static_cast<int32_t>(poll.count()));
191}
192
193} // namespace nros
194
195// -- Executor std::chrono member-like free functions --
196
197namespace nros {
198
200inline Result executor_spin_once(Executor& exec, std::chrono::milliseconds timeout) {
201 return exec.spin_once(static_cast<int32_t>(timeout.count()));
202}
203
205inline Result executor_spin(Executor& exec, std::chrono::milliseconds duration,
206 std::chrono::milliseconds poll = std::chrono::milliseconds(10)) {
207 return exec.spin(static_cast<uint32_t>(duration.count()), static_cast<int32_t>(poll.count()));
208}
209
210} // namespace nros
211
212#endif // NROS_CPP_STD
213
214#endif // NROS_CPP_STD_COMPAT_HPP
static Result create(Executor &out, const char *locator=nullptr, uint8_t domain_id=0)
Definition executor.hpp:64
Future()
Default constructor – creates an empty/consumed future.
Definition future.hpp:145
static constexpr QoS default_profile()
Default profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:160
static constexpr QoS services()
Services profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:166
Definition nros.hpp:42
Result spin()
Definition nros.hpp:77
Result spin_once(int32_t timeout_ms=10)
Definition nros.hpp:62
Result init(const char *locator=nullptr, uint8_t domain_id=0)
Definition node.hpp:568
Result create_node(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:728