24 assert(code_.
isBad());
60 constexpr Result() noexcept(std::is_nothrow_default_constructible_v<T>)
61 : code_(UA_STATUSCODE_GOOD),
71 )
noexcept(std::is_nothrow_copy_constructible_v<T>)
74 assert(!code_.
isBad());
82 )
noexcept(std::is_nothrow_move_constructible_v<T>)
84 maybeValue_(std::move(
value)) {
85 assert(!code_.
isBad());
92 : code_(error.code()),
93 maybeValue_(std::nullopt) {}
104 return &(*maybeValue_);
109 return &(*maybeValue_);
127 return std::move(*maybeValue_);
132 return std::move(*maybeValue_);
147 constexpr explicit operator bool() const noexcept {
155 return maybeValue_.has_value();
176 return std::move(**
this);
180 constexpr const T&&
value() const&& {
182 return std::move(**
this);
189 template <
typename U>
190 constexpr T
valueOr(U&& defaultValue)
const& {
191 return !isBad() ? **this :
static_cast<T
>(std::forward<U>(defaultValue));
195 template <
typename U>
197 return !isBad() ? std::move(**
this) :
static_cast<T
>(std::forward<U>(defaultValue));
206 template <
typename F>
208 return transformImpl(*
this, std::forward<F>(func));
212 template <
typename F>
214 return transformImpl(*
this, std::forward<F>(func));
218 template <
typename F>
220 return transformImpl(std::move(*
this), std::forward<F>(func));
224 template <
typename F>
226 return transformImpl(std::move(*
this), std::forward<F>(func));
235 template <
typename F>
237 return andThenImpl(*
this, std::forward<F>(func));
241 template <
typename F>
243 return andThenImpl(*
this, std::forward<F>(func));
247 template <
typename F>
249 return andThenImpl(std::move(*
this), std::forward<F>(func));
253 template <
typename F>
255 return andThenImpl(std::move(*
this), std::forward<F>(func));
264 template <
typename F>
266 return orElseImpl(*
this, std::forward<F>(func));
270 template <
typename F>
272 return orElseImpl(*
this, std::forward<F>(func));
276 template <
typename F>
278 return orElseImpl(std::move(*
this), std::forward<F>(func));
282 template <
typename F>
283 constexpr auto orElse(F&& func)
const&& {
284 return orElseImpl(std::move(*
this), std::forward<F>(func));
288 template <
typename Self,
typename F>
289 static auto transformImpl(Self&& self, F&& func) {
290 using Value =
decltype(*std::forward<Self>(self));
291 using NewValue = std::remove_cv_t<std::invoke_result_t<F, Value>>;
292 if (self.hasValue()) {
293 if constexpr (std::is_void_v<NewValue>) {
297 std::invoke(std::forward<F>(func), *std::forward<Self>(self)), self.code()
305 template <
typename Self,
typename F>
306 static auto andThenImpl(Self&& self, F&& func) {
307 using Value =
decltype(*std::forward<Self>(self));
308 if constexpr (std::is_invocable_v<F, Value, StatusCode>) {
309 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value, StatusCode>>;
310 return self.hasValue()
311 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self), self.code())
312 : NewResult(BadResult(self.
code()));
314 using NewResult = std::remove_cv_t<std::invoke_result_t<F, Value>>;
315 return self.hasValue()
316 ? std::invoke(std::forward<F>(func), *std::forward<Self>(self))
317 : NewResult(BadResult(self.
code()));
321 template <
typename Self,
typename F>
322 static auto orElseImpl(Self&& self, F&& func) {
323 using NewResult = std::remove_cv_t<std::invoke_result_t<F,
decltype(self.code())>>;
324 return self.hasValue()
325 ? std::forward<Self>(self)
326 : NewResult(std::invoke(std::forward<F>(func), self.
code()));
329 constexpr bool isBad() const noexcept {
333 constexpr void checkIsBad()
const {
338 std::optional<T> maybeValue_;
352 : code_(UA_STATUSCODE_GOOD) {}
364 : code_(error.code()) {}
378 constexpr explicit operator bool() const noexcept {
386 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 with a value and a StatusCode (good or uncertain).
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
Create a Result with the given error.
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 with a value and a StatusCode (good or uncertain).
UA_StatusCode wrapper class.
constexpr void throwIfBad() const
Throw a BadStatus exception if the status code is bad.
constexpr bool isBad() const noexcept
Check if the status code is bad.
@ Value
The most recent value of the variable that the server has.