Skip to content

Commit

Permalink
expected: Allow to move-assign from move-only unexpected (#40)
Browse files Browse the repository at this point in the history
Fix concept checks in the assignment operators (thanks @szaszm)
  • Loading branch information
szaszm committed Dec 7, 2021
1 parent b803e3c commit b5dfa99
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ expected: Allows to move-assign from expected, error
expected: Allows to forward-assign from value
expected: Allows to copy-assign from unexpected
expected: Allows to move-assign from unexpected
expected: Allows to move-assign from move-only unexpected
expected: Allows to emplace value
expected: Allows to emplace value from initializer_list
expected: Allows to be swapped
Expand Down
14 changes: 8 additions & 6 deletions include/nonstd/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1664,10 +1664,11 @@ class expected
return *this;
}

template< typename G
template< typename G = E
nsel_REQUIRES_T(
std::is_copy_constructible<E>::value // TODO: std::is_nothrow_copy_constructible<E>
&& std::is_copy_assignable<E>::value
std::is_constructible<E, G const&>::value &&
std::is_copy_constructible<G>::value // TODO: std::is_nothrow_copy_constructible<G>
&& std::is_copy_assignable<G>::value
)
>
expected & operator=( nonstd::unexpected_type<G> const & error )
Expand All @@ -1676,10 +1677,11 @@ class expected
return *this;
}

template< typename G
template< typename G = E
nsel_REQUIRES_T(
std::is_move_constructible<E>::value // TODO: std::is_nothrow_move_constructible<E>
&& std::is_move_assignable<E>::value
std::is_constructible<E, G&&>::value &&
std::is_move_constructible<G>::value // TODO: std::is_nothrow_move_constructible<G>
&& std::is_move_assignable<G>::value
)
>
expected & operator=( nonstd::unexpected_type<G> && error )
Expand Down
22 changes: 22 additions & 0 deletions test/expected.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ using namespace nonstd;

struct Implicit { int x; Implicit(int v) : x(v) {} };
struct Explicit { int x; explicit Explicit(int v) : x(v) {} };
struct MoveOnly {
int x;
explicit MoveOnly(int x) :x{x} {}
MoveOnly(const MoveOnly&) = delete;
MoveOnly(MoveOnly&& other) noexcept :x{other.x} {}
MoveOnly& operator=(const MoveOnly&) = delete;
MoveOnly& operator=(MoveOnly&& other) noexcept {
if (&other == this) return *this;
x = other.x;
return *this;
}
};

bool operator==( Implicit a, Implicit b ) { return a.x == b.x; }
bool operator==( Explicit a, Explicit b ) { return a.x == b.x; }
Expand Down Expand Up @@ -902,6 +914,16 @@ CASE( "expected: Allows to move-assign from unexpected" )
EXPECT( e.error() == 7 );
}

CASE( "expected: Allows to move-assign from move-only unexpected" )
{
expected<char, MoveOnly> e;
unexpected_type<MoveOnly> u{7};

e = std::move( u );

EXPECT( e.error() == 7 );
}

CASE( "expected: Allows to emplace value" )
{
expected<int, char> a;
Expand Down

0 comments on commit b5dfa99

Please sign in to comment.