Skip to content

Commit

Permalink
Improve move semantics in Expected (XRPLF#4326)
Browse files Browse the repository at this point in the history
* Improve move semantics in Expected:

This patch unconditionally moves an `Unexpected<U>` value parameter as
long as `U` is not a reference. If `U` is a reference the code should
not compile. An error type that holds a reference is a strange use-case,
and an overload is not provided. If it is required in the future it can
be added.

The `Expected(U r)` overload should take a forwarding ref.

* Replace enable_if with concepts in Expected
  • Loading branch information
seelabs authored and dangell7 committed Mar 5, 2023
1 parent f472d10 commit 6e35b7f
Showing 1 changed file with 14 additions and 12 deletions.
26 changes: 14 additions & 12 deletions src/ripple/basics/Expected.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
#define RIPPLE_BASICS_EXPECTED_H_INCLUDED

#include <ripple/basics/contract.h>

#include <boost/outcome.hpp>

#include <concepts>
#include <stdexcept>
#include <type_traits>

Expand Down Expand Up @@ -132,17 +135,16 @@ class [[nodiscard]] Expected
using Base = boost::outcome_v2::result<T, E, detail::throw_policy>;

public:
template <
typename U,
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr Expected(U r) : Base(T{std::forward<U>(r)})
template <typename U>
requires std::convertible_to<U, T> constexpr Expected(U && r)
: Base(T{std::forward<U>(r)})
{
}

template <
typename U,
typename = std::enable_if_t<std::is_convertible_v<U, E>>>
constexpr Expected(Unexpected<U> e) : Base(E{std::forward<U>(e.value())})
template <typename U>
requires std::convertible_to<U, E> &&
(!std::is_reference_v<U>)constexpr Expected(Unexpected<U> e)
: Base(E{std::move(e.value())})
{
}

Expand Down Expand Up @@ -215,10 +217,10 @@ class [[nodiscard]] Expected<void, E>
{
}

template <
typename U,
typename = std::enable_if_t<std::is_convertible_v<U, E>>>
constexpr Expected(Unexpected<U> e) : Base(E{std::forward<U>(e.value())})
template <typename U>
requires std::convertible_to<U, E> &&
(!std::is_reference_v<U>)constexpr Expected(Unexpected<U> e)
: Base(E{std::move(e.value())})
{
}

Expand Down

0 comments on commit 6e35b7f

Please sign in to comment.