24 assert(code_.
isBad());
60 constexpr Result() noexcept(std::is_nothrow_default_constructible_v<T>)
61 : code_(UA_STATUSCODE_GOOD),
70 const T& value,
StatusCode code = UA_STATUSCODE_GOOD
71 )
noexcept(std::is_nothrow_copy_constructible_v<T>)
79 T&& value,
StatusCode code = UA_STATUSCODE_GOOD
80 )
noexcept(std::is_nothrow_move_constructible_v<T>)
82 maybeValue_(std::move(value)) {}
88 : code_(error.code()),
89 maybeValue_(std::nullopt) {}
100 return &(*maybeValue_);
105 return &(*maybeValue_);
123 return std::move(*maybeValue_);
128 return std::move(*maybeValue_);
143 constexpr explicit operator bool() const noexcept {
151 return maybeValue_.has_value();
172 return std::move(**
this);
176 constexpr const T&&
value() const&& {
178 return std::move(**
this);
185 template <
typename U>
186 constexpr T
valueOr(U&& defaultValue)
const& {
187 return !isBad() ? **this :
static_cast<T
>(std::forward<U>(defaultValue));
191 template <
typename U>
193 return !isBad() ? std::move(**
this) :
static_cast<T
>(std::forward<U>(defaultValue));
202 template <
typename F>
204 return transformImpl(*
this, std::forward<F>(func));
208 template <
typename F>
210 return transformImpl(*
this, std::forward<F>(func));
214 template <
typename F>
216 return transformImpl(std::move(*
this), std::forward<F>(func));
220 template <
typename F>
222 return transformImpl(std::move(*
this), std::forward<F>(func));
231 template <
typename F>
233 return andThenImpl(*
this, std::forward<F>(func));
237 template <
typename F>
239 return andThenImpl(*
this, std::forward<F>(func));
243 template <
typename F>
245 return andThenImpl(std::move(*
this), std::forward<F>(func));
249 template <
typename F>
251 return andThenImpl(std::move(*
this), std::forward<F>(func));
260 template <
typename F>
262 return orElseImpl(*
this, std::forward<F>(func));
266 template <
typename F>
268 return orElseImpl(*
this, std::forward<F>(func));
272 template <
typename F>
274 return orElseImpl(std::move(*
this), std::forward<F>(func));
278 template <
typename F>
279 constexpr auto orElse(F&& func)
const&& {
280 return orElseImpl(std::move(*
this), std::forward<F>(func));
284 template <
typename Self,
typename F>
285 static auto transformImpl(Self&& self, F&& func) {
286 using Value =
decltype(*std::forward<Self>(self));
287 using NewValue = std::remove_cv_t<std::invoke_result_t<F, Value>>;
288 if (self.hasValue()) {
289 if constexpr (std::is_void_v<NewValue>) {
292 return Result<NewValue>(
293 std::invoke(std::forward<F>(func), *std::forward<Self>(self)), self.code()
297 return Result<NewValue>(BadResult(self.code()));
301 template <
typename Self,
typename F>
302 static auto andThenImpl(Self&& self, F&& func) {
303 using Value =
decltype(*std::forward<Self>(self));
304 if constexpr (std::is_invocable_v<F, Value, StatusCode>) {
305 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value, StatusCode>>;
306 return self.hasValue()
307 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self), self.code())
308 : NewResult(BadResult(self.code()));
310 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value>>;
311 return self.hasValue()
312 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self))
313 : NewResult(BadResult(self.code()));
317 template <
typename Self,
typename F>
318 static auto orElseImpl(Self&& self, F&& func) {
319 using NewResult = std::remove_cv_t<std::invoke_result_t<F,
decltype(self.code())>>;
320 return self.hasValue()
321 ? std::forward<Self>(self)
322 : NewResult(std::invoke(std::forward<F>(func), self.code()));
325 constexpr bool isBad() const noexcept {
326 return code().isBad();
329 constexpr void checkIsBad()
const {
334 std::optional<T> maybeValue_;
348 : code_(UA_STATUSCODE_GOOD) {}
360 : code_(error.code()) {}
374 constexpr explicit operator bool() const noexcept {
382 return !code_.isBad();
Represents a bad result stored in Result.
constexpr StatusCode code() const noexcept
Get the StatusCode.
constexpr BadResult(StatusCode code) noexcept
Construct a BadResult from a bad StatusCode.
constexpr void value() const
Get the value of the Result.
constexpr Result() noexcept
Create a default Result (good StatusCode).
constexpr bool hasValue() const noexcept
constexpr Result(BadResult error) noexcept
Create a Result with the given error.
constexpr Result(StatusCode code) noexcept
Create a Result with the given StatusCode.
constexpr StatusCode code() const noexcept
Get the code of the Result.
constexpr void operator*() const noexcept
The template class Result encapsulates a StatusCode and optionally a value.
constexpr auto orElse(F &&func) const &&
Transforms Result<T> with a bad StatusCode to Result<T> using the given function.
constexpr auto andThen(F &&func) const &&
Transforms Result<T> to Result<U> using the given function.
constexpr T valueOr(U &&defaultValue) &&
Get the value of the Result or a default value.
constexpr T & operator*() &noexcept
Get the value of the Result.
constexpr const T & value() const &
Get the value of the Result.
constexpr T valueOr(U &&defaultValue) const &
Get the value of the Result or a default value.
constexpr T && operator*() &&noexcept
Get the value of the Result.
constexpr auto transform(F &&func) &
Transforms Result<T> to Result<U> using the given value transformation function.
constexpr T && value() &&
Get the value of the Result.
constexpr const T & operator*() const &noexcept
Get the value of the Result.
constexpr auto orElse(F &&func) &&
Transforms Result<T> with a bad StatusCode to Result<T> using the given function.
constexpr Result() noexcept(std::is_nothrow_default_constructible_v< T >)
Default constructor (default-initialized value and good StatusCode).
constexpr bool hasValue() const noexcept
Check if the Result has a value.
constexpr auto andThen(F &&func) &&
Transforms Result<T> to Result<U> using the given function.
constexpr auto transform(F &&func) const &&
Transforms Result<T> to Result<U> using the given value transformation function.
constexpr auto orElse(F &&func) const &
Transforms Result<T> with a bad StatusCode to Result<T> using the given function.
constexpr const T && operator*() const &&noexcept
Get the value of the Result.
constexpr Result(const T &value, StatusCode code=UA_STATUSCODE_GOOD) noexcept(std::is_nothrow_copy_constructible_v< T >)
Construct a Result from a value (lvalue) and a StatusCode.
constexpr const T && value() const &&
Get the value of the Result.
constexpr auto transform(F &&func) &&
Transforms Result<T> to Result<U> using the given value transformation function.
constexpr auto orElse(F &&func) &
Transforms Result<T> with a bad StatusCode to Result<T> using the given function.
constexpr Result(BadResult error) noexcept
Construct a Result from a BadResult.
constexpr auto transform(F &&func) const &
Transforms Result<T> to Result<U> using the given value transformation function.
constexpr auto andThen(F &&func) const &
Transforms Result<T> to Result<U> using the given function.
constexpr auto andThen(F &&func) &
Transforms Result<T> to Result<U> using the given function.
constexpr T * operator->() noexcept
Get the value of the Result.
constexpr T & value() &
Get the value of the Result.
constexpr const T * operator->() const noexcept
Get the value of the Result.
constexpr StatusCode code() const noexcept
Get the StatusCode of the Result.
constexpr Result(T &&value, StatusCode code=UA_STATUSCODE_GOOD) noexcept(std::is_nothrow_move_constructible_v< T >)
Construct a Result from a value (rvalue) and a StatusCode.
UA_StatusCode wrapper class.
constexpr bool isBad() const noexcept
Check if the status code is bad.
@ Value
The most recent value of the variable that the server has.