Fixed copy and move operations on "expected<trivially_copyable,nontrivially_copyable"

This commit is contained in:
Kévin Alexandre Boissonneault
2017-12-02 19:12:22 -05:00
parent 492f03f447
commit 1b0056303d
2 changed files with 62 additions and 3 deletions

View File

@@ -591,7 +591,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
// This class manages conditionally having a trivial copy constructor
// This specialization is for when T is trivially copy constructible
template <class T, class E, bool = IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
template <class T, class E, bool = IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) && IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
@@ -612,7 +612,15 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
}
expected_copy_base(expected_copy_base &&rhs) = default;
expected_copy_base &operator=(const expected_copy_base &rhs) = default;
expected_copy_base &operator=(const expected_copy_base &rhs) {
if (rhs.has_value()) {
this->construct(rhs.get());
}
else {
this->construct_error(rhs.geterr());
}
return *this;
}
expected_copy_base &operator=(expected_copy_base &&rhs) = default;
};
@@ -718,7 +726,7 @@ template <class T, class E,
bool EnableCopy = (std::is_copy_constructible<T>::value &&
std::is_copy_constructible<E>::value),
bool EnableMove = (std::is_move_constructible<T>::value &&
std::is_move_constructible<T>::value)>
std::is_move_constructible<E>::value)>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base &) = default;

View File

@@ -59,4 +59,55 @@ TEST_CASE("Constructors", "[constructors]") {
REQUIRE(std::get<1>(e->t) == 3);
}
{
tl::expected<int, int> e;
REQUIRE(std::is_default_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
REQUIRE(std::is_trivially_copy_constructible<decltype(e)>::value);
REQUIRE(std::is_move_constructible<decltype(e)>::value);
REQUIRE(std::is_trivially_move_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
REQUIRE(std::is_trivially_copy_assignable<decltype(e)>::value);
REQUIRE(std::is_move_assignable<decltype(e)>::value);
REQUIRE(std::is_trivially_move_assignable<decltype(e)>::value);
}
{
tl::expected<int, std::string> e;
REQUIRE(std::is_default_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_constructible<decltype(e)>::value);
REQUIRE(std::is_move_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_assignable<decltype(e)>::value);
REQUIRE(std::is_move_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
}
{
tl::expected<std::string, int> e;
REQUIRE(std::is_default_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_constructible<decltype(e)>::value);
REQUIRE(std::is_move_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_assignable<decltype(e)>::value);
REQUIRE(std::is_move_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
}
{
tl::expected<std::string, std::string> e;
REQUIRE(std::is_default_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_constructible<decltype(e)>::value);
REQUIRE(std::is_move_constructible<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_copy_assignable<decltype(e)>::value);
REQUIRE(std::is_move_assignable<decltype(e)>::value);
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
}
}