nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1// nros-cpp: Result type for error handling
2// Freestanding C++ — no exceptions, no STL required
3
12#ifndef NROS_CPP_RESULT_HPP
13#define NROS_CPP_RESULT_HPP
14
15#include <cstdint>
16#include <utility>
17#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
18#include <cstdio>
19#endif
20
21namespace nros {
22
30enum class ErrorCode : int32_t {
32 Ok = 0,
34 Error = -1,
36 Timeout = -2,
38 InvalidArgument = -3,
40 NotFound = -4,
42 AlreadyExists = -5,
44 Full = -6,
47 NotInitialized = -7,
49 BadSequence = -8,
51 ServiceFailed = -9,
53 PublishFailed = -10,
57 NotAllowed = -12,
59 Rejected = -13,
61 TryAgain = -14,
63 Reentrant = -15,
65 Unsupported = -16,
67 TransportError = -100,
68};
69
70// Issue #229 pin (self-consistency half): the values above ARE the shared
71// numbering. The cross-space asserts against the real C constants live in
72// parameter.hpp (vs NROS_RET_*) and node.hpp (vs NROS_CPP_RET_*), where
73// those headers are visible.
74static_assert(static_cast<int32_t>(ErrorCode::NotFound) == -4 &&
75 static_cast<int32_t>(ErrorCode::AlreadyExists) == -5 &&
76 static_cast<int32_t>(ErrorCode::Full) == -6 &&
77 static_cast<int32_t>(ErrorCode::NotInitialized) == -7 &&
78 static_cast<int32_t>(ErrorCode::TryAgain) == -14 &&
79 static_cast<int32_t>(ErrorCode::Reentrant) == -15 &&
80 static_cast<int32_t>(ErrorCode::Unsupported) == -16,
81 "ErrorCode numbering must match nros_ret_t (issue #229)");
82
87class Result {
88 public:
90 constexpr Result() : code_(ErrorCode::Ok) {}
92 constexpr Result(ErrorCode code) : code_(code) {}
94 constexpr Result(int32_t raw) : code_(static_cast<ErrorCode>(raw)) {}
95
97 bool ok() const { return code_ == ErrorCode::Ok; }
98
100 explicit operator bool() const { return ok(); }
101
103 ErrorCode code() const { return code_; }
104
106 int32_t raw() const { return static_cast<int32_t>(code_); }
107
109 static constexpr Result success() { return Result(ErrorCode::Ok); }
110
111 private:
112 ErrorCode code_;
113};
114
125#define NROS_TRY(expr) \
126 do { \
127 ::nros::Result _nros_r = (expr); \
128 if (!_nros_r.ok()) return _nros_r; \
129 } while (0)
130
144#ifndef NROS_TRY_LOG
145#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
146#define NROS_TRY_LOG(file, line, expr, ret) \
147 ::std::fprintf(stderr, "[nros] %s:%d %s -> %d\n", (file), (line), (expr), (int)(ret))
148#else
149#define NROS_TRY_LOG(file, line, expr, ret) ((void)(file), (void)(line), (void)(expr), (void)(ret))
150#endif
151#endif
152
153#define NROS_TRY_RET(expr, retval) \
154 do { \
155 ::nros::Result _nros_r = (expr); \
156 if (!_nros_r.ok()) { \
157 NROS_TRY_LOG(__FILE__, __LINE__, #expr, _nros_r.raw()); \
158 return (retval); \
159 } \
160 } while (0)
161
165#define NROS_CHECK(expr) \
166 do { \
167 ::nros::Result _nros_r = (expr); \
168 if (!_nros_r.ok()) { \
169 NROS_TRY_LOG(__FILE__, __LINE__, #expr, _nros_r.raw()); \
170 return; \
171 } \
172 } while (0)
173
195template <typename T> class Expected {
196 public:
197 static Expected ok(T value) {
198 Expected e;
199 e.ok_ = true;
200 e.value_ = ::std::move(value);
201 return e;
202 }
203 static Expected error(ErrorCode code) {
204 Expected e;
205 e.ok_ = false;
206 e.error_ = code;
207 return e;
208 }
209 static Expected error(const Result& r) { return error(r.code()); }
210
211 bool ok() const { return ok_; }
212 explicit operator bool() const { return ok_; }
213
214 T& value() & { return value_; }
215 const T& value() const& { return value_; }
216 T&& value() && { return ::std::move(value_); }
217
218 ErrorCode error() const { return error_; }
219 Result error_as_result() const { return Result(error_); }
220
221 private:
222 Expected() : ok_(false), error_(ErrorCode::Error), value_() {}
223
224 bool ok_;
225 ErrorCode error_;
226 T value_;
227};
228
229} // namespace nros
230
231#endif // NROS_CPP_RESULT_HPP
Definition result.hpp:195
Result error_as_result() const
Definition result.hpp:219
T & value() &
Definition result.hpp:214
const T & value() const &
Definition result.hpp:215
static Expected error(ErrorCode code)
Definition result.hpp:203
static Expected error(const Result &r)
Definition result.hpp:209
static Expected ok(T value)
Definition result.hpp:197
ErrorCode error() const
Definition result.hpp:218
T && value() &&
Definition result.hpp:216
bool ok() const
Definition result.hpp:211
Definition future.hpp:40
Definition result.hpp:87
static constexpr Result success()
Named constructors.
Definition result.hpp:109
int32_t raw() const
Get the raw integer code (for FFI interop).
Definition result.hpp:106
ErrorCode code() const
Get the underlying error code.
Definition result.hpp:103
constexpr Result(ErrorCode code)
Construct from a typed code.
Definition result.hpp:92
constexpr Result(int32_t raw)
Construct from a raw FFI return value (int32_t).
Definition result.hpp:94
bool ok() const
Returns true if the operation succeeded.
Definition result.hpp:97
constexpr Result()
Default-construct a success.
Definition result.hpp:90
Definition nros.hpp:43
ErrorCode
Definition result.hpp:30
@ InvalidArgument
Null pointer, empty topic name, or out-of-range value.
@ NotFound
Entity not found (topic, parameter, service…).
@ Reentrant
A blocking call was made from inside a callback.
@ PublishFailed
Publish failed.
@ BadSequence
Operation invalid in the current state (bad call sequence).
@ ServiceFailed
Service request/reply failed.
@ AlreadyExists
Already exists (duplicate declare/register).
@ Error
Generic failure not covered by a more specific code.
@ TransportError
Underlying zenoh-pico / DDS transport rejected the operation.
@ Unsupported
Operation not implemented by the active backend.
@ Full
Static pool exhausted (executor slots, subscription buffers, …).
@ Timeout
Operation deadline elapsed before completion.
@ Rejected
Rejected (QoS/ABI incompatibility).
@ SubscriptionFailed
Subscription create/take failed.
@ TryAgain
Transient — no data ready yet (non-blocking take). Retry later.
@ NotAllowed
Operation not allowed for this entity/backend.