23 : code_{std::move(
code)} {
24 assert(code_.
isBad());
60 template <
typename U = T, std::enable_if_t<std::is_default_constructible_v<U>,
int> = 0>
61 constexpr Result() noexcept(std::is_nothrow_default_constructible_v<T>)
63 maybeValue_{std::in_place} {}
71 const T& value,
StatusCode code = UA_STATUSCODE_GOOD
72 )
noexcept(std::is_nothrow_copy_constructible_v<T>)
73 : code_{std::move(code)},
80 T&& value,
StatusCode code = UA_STATUSCODE_GOOD
81 )
noexcept(std::is_nothrow_move_constructible_v<T>)
82 : code_{std::move(code)},
83 maybeValue_{std::move(value)} {}
89 : code_{error.code()},
90 maybeValue_{std::nullopt} {}
101 return &(*maybeValue_);
106 return &(*maybeValue_);
124 return std::move(*maybeValue_);
129 return std::move(*maybeValue_);
144 constexpr explicit operator bool() const noexcept {
152 return maybeValue_.has_value();
173 return std::move(**
this);
177 constexpr const T&&
value() const&& {
179 return std::move(**
this);
186 template <
typename U>
187 constexpr T
valueOr(U&& defaultValue)
const& {
188 return !isBad() ? **this :
static_cast<T
>(std::forward<U>(defaultValue));
192 template <
typename U>
194 return !isBad() ? std::move(**
this) :
static_cast<T
>(std::forward<U>(defaultValue));
203 template <
typename F>
205 return transformImpl(*
this, std::forward<F>(func));
209 template <
typename F>
211 return transformImpl(*
this, std::forward<F>(func));
215 template <
typename F>
217 return transformImpl(std::move(*
this), std::forward<F>(func));
221 template <
typename F>
223 return transformImpl(std::move(*
this), std::forward<F>(func));
232 template <
typename F>
234 return andThenImpl(*
this, std::forward<F>(func));
238 template <
typename F>
240 return andThenImpl(*
this, std::forward<F>(func));
244 template <
typename F>
246 return andThenImpl(std::move(*
this), std::forward<F>(func));
250 template <
typename F>
252 return andThenImpl(std::move(*
this), std::forward<F>(func));
261 template <
typename F>
263 return orElseImpl(*
this, std::forward<F>(func));
267 template <
typename F>
269 return orElseImpl(*
this, std::forward<F>(func));
273 template <
typename F>
275 return orElseImpl(std::move(*
this), std::forward<F>(func));
279 template <
typename F>
280 constexpr auto orElse(F&& func)
const&& {
281 return orElseImpl(std::move(*
this), std::forward<F>(func));
285 template <
typename Self,
typename F>
286 static auto transformImpl(Self&& self, F&& func) {
287 using Value =
decltype(*std::forward<Self>(self));
288 using NewValue = std::remove_cv_t<std::invoke_result_t<F, Value>>;
289 if (self.hasValue()) {
290 if constexpr (std::is_void_v<NewValue>) {
293 return Result<NewValue>(
294 std::invoke(std::forward<F>(func), *std::forward<Self>(self)), self.code()
298 return Result<NewValue>(BadResult(self.code()));
302 template <
typename Self,
typename F>
303 static auto andThenImpl(Self&& self, F&& func) {
304 using Value =
decltype(*std::forward<Self>(self));
305 if constexpr (std::is_invocable_v<F, Value, StatusCode>) {
306 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value, StatusCode>>;
307 return self.hasValue()
308 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self), self.code())
309 : NewResult(BadResult(self.code()));
311 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value>>;
312 return self.hasValue()
313 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self))
314 : NewResult(BadResult(self.code()));
318 template <
typename Self,
typename F>
319 static auto orElseImpl(Self&& self, F&& func) {
320 using NewResult = std::remove_cv_t<std::invoke_result_t<F,
decltype(self.code())>>;
321 return self.hasValue()
322 ? std::forward<Self>(self)
323 : NewResult(std::invoke(std::forward<F>(func), self.code()));
326 constexpr bool isBad() const noexcept {
327 return code().isBad();
330 constexpr void checkIsBad()
const {
335 std::optional<T> maybeValue_;
355 : code_{std::move(code)} {}
361 : code_{error.code()} {}
375 constexpr explicit operator bool() const noexcept {
383 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(StatusCode code) noexcept
Create a Result with the given StatusCode.
constexpr Result(const BadResult &error) noexcept
Create a Result with the given error.
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 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 Result(const BadResult &error) noexcept
Construct a Result from a BadResult.
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() noexcept(std::is_nothrow_default_constructible_v< T >)
Default constructor (default-initialized value and good StatusCode).
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.
#define UA_STATUSCODE_GOOD