39#include <initializer_list>
45#include "pw_containers/internal/optional_data.h"
46#include "pw_preprocessor/compiler.h"
47#include "pw_result/internal/result_internal.h"
48#include "pw_status/status.h"
141 :
private containers::internal::OptionalData<T, pw_Status, PW_STATUS_OK>,
142 private containers::internal::CopyCtorBase<T>,
143 private containers::internal::MoveCtorBase<T>,
144 private containers::internal::CopyAssignBase<T>,
145 private containers::internal::MoveAssignBase<T> {
146 template <
typename U>
149 using Base = containers::internal::OptionalData<T, pw_Status, PW_STATUS_OK>;
164 explicit constexpr Result();
191 std::negation<std::is_same<T, U>>,
192 std::is_constructible<T, const U&>,
193 std::is_convertible<const U&, T>,
194 std::negation<internal_result::
195 IsConstructibleOrConvertibleFromResult<T, U>>>
::
199 : Base(static_cast<const typename
Result<U>::Base&>(other)) {}
204 std::negation<std::is_same<T, U>>,
205 std::is_constructible<T, const U&>,
206 std::negation<std::is_convertible<const U&, T>>,
207 std::negation<internal_result::
208 IsConstructibleOrConvertibleFromResult<T, U>>>
::
212 : Base(static_cast<const typename
Result<U>::Base&>(other)) {}
218 std::negation<std::is_same<T, U>>,
219 std::is_constructible<T, U&&>,
220 std::is_convertible<U&&, T>,
221 std::negation<internal_result::
222 IsConstructibleOrConvertibleFromResult<T, U>>>
::
225 constexpr Result(Result<U>&& other)
226 : Base(static_cast<typename Result<U>::Base&&>(other)) {}
231 std::negation<std::is_same<T, U>>,
232 std::is_constructible<T, U&&>,
233 std::negation<std::is_convertible<U&&, T>>,
234 std::negation<internal_result::
235 IsConstructibleOrConvertibleFromResult<T, U>>>
::
238 explicit constexpr Result(Result<U>&& other)
239 : Base(static_cast<typename Result<U>::Base&&>(other)) {}
256 template <
typename U,
259 std::negation<std::is_same<T, U>>,
260 std::is_constructible<T, const U&>,
261 std::is_assignable<T, const U&>,
264 IsConstructibleOrConvertibleOrAssignableFromResult<
272 template <
typename U,
275 std::negation<std::is_same<T, U>>,
276 std::is_constructible<T, U&&>,
277 std::is_assignable<T, U&&>,
280 IsConstructibleOrConvertibleOrAssignableFromResult<
285 this->Assign(std::move(other));
305 std::is_convertible<U&&, Status>,
306 std::is_constructible<Status, U&&>,
307 std::negation<std::is_same<std::decay_t<U>, Result<T>>>,
308 std::negation<std::is_same<std::decay_t<U>, T>>,
309 std::negation<std::is_same<std::decay_t<U>, std::in_place_t>>,
310 std::negation<internal_result::
311 HasConversionOperatorToResult<T, U&&>>>
::value,
314 : Base(static_cast<
Status>(std::forward<U>(v)).code()) {}
320 std::negation<std::is_convertible<U&&, Status>>,
321 std::is_constructible<Status, U&&>,
322 std::negation<std::is_same<std::decay_t<U>,
Result<T>>>,
323 std::negation<std::is_same<std::decay_t<U>, T>>,
324 std::negation<std::is_same<std::decay_t<U>, std::in_place_t>>,
325 std::negation<internal_result::
326 HasConversionOperatorToResult<T, U&&>>>
::value,
328 constexpr explicit Result(U&& v)
329 : Base(static_cast<
Status>(std::forward<U>(v)).code()) {}
335 std::is_convertible<U&&, Status>,
336 std::is_constructible<Status, U&&>,
337 std::negation<std::is_same<std::decay_t<U>, Result<T>>>,
338 std::negation<std::is_same<std::decay_t<U>, T>>,
339 std::negation<std::is_same<std::decay_t<U>, std::in_place_t>>,
340 std::negation<internal_result::
341 HasConversionOperatorToResult<T, U&&>>>
::value,
344 this->AssignState(
static_cast<Status
>(std::forward<U>(v)).code());
368 typename =
typename std::enable_if<std::conjunction<
369 std::is_constructible<T, U&&>,
370 std::is_assignable<T&, U&&>,
372 std::is_same<std::remove_cv_t<std::remove_reference_t<U>>, T>,
374 std::negation<std::is_convertible<U&&, Status>>,
376 internal_result::HasConversionOperatorToResult<T, U&&>>>>,
377 internal_result::IsForwardingAssignmentValid<T, U&&>>
::value>::type>
379 this->Assign(std::forward<U>(v));
385 template <
typename... Args>
386 explicit constexpr Result(std::in_place_t, Args&&... args);
387 template <
typename U,
typename... Args>
388 explicit constexpr Result(std::in_place_t,
389 std::initializer_list<U> ilist,
405 internal_result::IsDirectInitializationValid<T, U&&>,
406 std::is_constructible<T, U&&>,
407 std::is_convertible<U&&, T>,
409 std::is_same<std::remove_cv_t<std::remove_reference_t<U>>, T>,
411 std::negation<std::is_convertible<U&&, Status>>,
414 HasConversionOperatorToResult<T, U&&>>>>>
::value,
417 :
Result(std::in_place, std::forward<U>(u)) {}
423 internal_result::IsDirectInitializationValid<T, U&&>,
425 std::is_same<std::remove_cv_t<std::remove_reference_t<U>>, T>,
427 std::negation<std::is_constructible<Status, U&&>>,
430 HasConversionOperatorToResult<T, U&&>>>>,
431 std::is_constructible<T, U&&>,
432 std::negation<std::is_convertible<U&&, T>>>
::value,
434 explicit constexpr Result(U&& u)
435 :
Result(std::in_place, std::forward<U>(u)) {}
451 [[nodiscard]]
constexpr bool ok()
const {
527 template <typename U>
529 template <typename U>
530 constexpr T
value_or(U&& default_value) &&;
540 template <typename... Args>
544 this->MakeValue(std::forward<Args>(args)...);
546 this->MakeValue(std::forward<Args>(args)...);
556 std::is_constructible<T, std::initializer_list<U>&, Args&&...>
::value,
558 T&
emplace(std::initializer_list<U> ilist, Args&&... args) {
561 this->MakeValue(ilist, std::forward<Args>(args)...);
563 this->MakeValue(ilist, std::forward<Args>(args)...);
588 template <
typename Fn,
589 typename Ret = internal_result::InvokeResultType<Fn, T&>,
590 std::enable_if_t<std::is_copy_constructible_v<Ret>,
int> = 0>
592 static_assert(internal_result::IsResult<Ret>,
593 "Fn must return a pw::Result");
594 return ok() ? std::invoke(std::forward<Fn>(function),
value())
598 template <
typename Fn,
599 typename Ret = internal_result::InvokeResultType<Fn, T&&>,
600 std::enable_if_t<std::is_move_constructible_v<Ret>,
int> = 0>
601 constexpr auto and_then(Fn&& function) && {
602 static_assert(internal_result::IsResult<Ret>,
603 "Fn must return a pw::Result");
604 return ok() ? std::invoke(std::forward<Fn>(function), std::move(
value()))
608 template <
typename Fn,
609 typename Ret = internal_result::InvokeResultType<Fn, const T&>,
610 std::enable_if_t<std::is_copy_constructible_v<Ret>,
int> = 0>
611 constexpr auto and_then(Fn&& function)
const& {
612 static_assert(internal_result::IsResult<Ret>,
613 "Fn must return a pw::Result");
614 return ok() ? std::invoke(std::forward<Fn>(function),
value())
618 template <
typename Fn,
619 typename Ret = internal_result::InvokeResultType<Fn, const T&&>,
620 std::enable_if_t<std::is_move_constructible_v<Ret>,
int> = 0>
621 constexpr auto and_then(Fn&& function)
const&& {
622 static_assert(internal_result::IsResult<Ret>,
623 "Fn must return a pw::Result");
624 return ok() ? std::invoke(std::forward<Fn>(function), std::move(
value()))
650 template <
typename Fn,
651 typename Ret = internal_result::InvokeResultType<Fn, const Status&>,
652 std::enable_if_t<!std::is_void_v<Ret>,
int> = 0>
654 static_assert(std::is_convertible_v<Ret, Result<T>>,
655 "Fn must be convertible to a pw::Result");
656 return ok() ? *this : std::invoke(std::forward<Fn>(function),
status());
659 template <
typename Fn,
660 typename Ret = internal_result::InvokeResultType<Fn, const Status&>,
661 std::enable_if_t<std::is_void_v<Ret>,
int> = 0>
666 std::invoke(std::forward<Fn>(function),
status());
670 template <
typename Fn,
671 typename Ret = internal_result::InvokeResultType<Fn, Status&&>,
672 std::enable_if_t<!std::is_void_v<Ret>,
int> = 0>
673 constexpr Result<T>
or_else(Fn&& function) && {
674 static_assert(std::is_convertible_v<Ret, Result<T>>,
675 "Fn must be convertible to a pw::Result");
676 return ok() ? std::move(*
this)
677 : std::invoke(std::forward<Fn>(function), std::move(
status()));
680 template <
typename Fn,
681 typename Ret = internal_result::InvokeResultType<Fn, Status&&>,
682 std::enable_if_t<std::is_void_v<Ret>,
int> = 0>
683 constexpr Result<T>
or_else(Fn&& function) && {
687 std::invoke(std::forward<Fn>(function),
status());
688 return std::move(*
this);
701 template <
typename Fn,
702 typename Ret = internal_result::InvokeResultType<Fn, T&>,
703 std::enable_if_t<std::is_copy_constructible_v<Ret>,
int> = 0>
708 return std::invoke(std::forward<Fn>(function),
value());
711 template <
typename Fn,
712 typename Ret = internal_result::InvokeResultType<Fn, T&&>,
713 std::enable_if_t<std::is_move_constructible_v<Ret>,
int> = 0>
716 return std::move(
status());
718 return std::invoke(std::forward<Fn>(function), std::move(
value()));
721 template <
typename Fn,
722 typename Ret = internal_result::InvokeResultType<Fn, T&>,
723 std::enable_if_t<std::is_copy_constructible_v<Ret>,
int> = 0>
724 constexpr Result<Ret>
transform(Fn&& function)
const& {
728 return std::invoke(std::forward<Fn>(function),
value());
731 template <
typename Fn,
732 typename Ret = internal_result::InvokeResultType<Fn, T&&>,
733 std::enable_if_t<std::is_move_constructible_v<Ret>,
int> = 0>
734 constexpr Result<Ret>
transform(Fn&& function)
const&& {
736 return std::move(
status());
738 return std::invoke(std::forward<Fn>(function), std::move(
value()));
743 template <
typename U>
744 constexpr void Assign(
const Result<U>& other);
745 template <
typename U>
746 constexpr void Assign(Result<U>&& other);
756 if (lhs.
ok() && rhs.
ok()) {
765 return !(lhs == rhs);
781 this->Assign(*other);
789constexpr inline void Result<T>::Assign(Result<U>&& other) {
791 this->
Assign(*std::move(other));
793 this->AssignState(std::move(other).status().code());
797template <
typename... Args>
799 : Base(std::in_place, std::forward<Args>(args)...) {}
802template <
typename U,
typename... Args>
804 std::initializer_list<U> ilist,
806 : Base(std::in_place, ilist, std::forward<Args>(args)...) {}
828 return std::move(this->data_);
834 return std::move(this->data_);
852 return std::move(this->data_);
858 return std::move(this->data_);
879 return std::forward<U>(default_value);
886 return std::move(this->data_);
888 return std::forward<U>(default_value);
904constexpr T&& ConvertToValue(Result<T>& result) {
905 return std::move(result).value();
constexpr const T & operator*() const &PW_ATTRIBUTE_LIFETIME_BOUND
Definition: result.h:838
constexpr Result(const Result &)=default
Result<T> is copy constructible if T is copy constructible.
constexpr Result(const Result< U > &other)
Definition: result.h:198
T & emplace(Args &&... args)
Definition: result.h:541
constexpr Result & operator=(Result &&)=default
constexpr Result(U &&u)
Definition: result.h:416
constexpr Result< T > or_else(Fn &&function) const &
Definition: result.h:653
constexpr void IgnoreError() const
Definition: result.h:892
constexpr Result & operator=(U &&v)
Definition: result.h:378
constexpr bool ok() const
Definition: result.h:451
constexpr const T & value() const &PW_ATTRIBUTE_LIFETIME_BOUND
Definition: result.h:814
constexpr const T * operator->() const PW_ATTRIBUTE_LIFETIME_BOUND
Definition: result.h:862
constexpr Result & operator=(const Result< U > &other)
Definition: result.h:268
constexpr T value_or(U &&default_value) const &
constexpr Result & operator=(const Result &)=default
constexpr Ret and_then(Fn &&function) &
Definition: result.h:591
constexpr Status status() const
Definition: result.h:809
T value_type
Definition: result.h:155
constexpr Result< Ret > transform(Fn &&function) &
Definition: result.h:704
constexpr Result(U &&v)
Definition: result.h:313
constexpr Result(Result &&)=default
Result<T> is move constructible if T is move constructible.
constexpr Code code() const
Definition: status.h:341
#define PW_ATTRIBUTE_LIFETIME_BOUND
Definition: compiler.h:273
Result(T value) -> Result< T >
Deduction guide to allow Result(v) rather than Result<T>(v).
constexpr Status OkStatus()
Definition: status.h:450
Status Assign(InlineString<> &string, std::string_view view)
Definition: util.h:142
The Pigweed namespace.
Definition: alignment.h:27