From 1b0056303d9446eb3646b9e19fa91794580cfa66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 19:12:22 -0500 Subject: [PATCH 1/6] Fixed copy and move operations on "expected { // This class manages conditionally having a trivial copy constructor // This specialization is for when T is trivially copy constructible -template +template struct expected_copy_base : expected_operations_base { using expected_operations_base::expected_operations_base; }; @@ -612,7 +612,15 @@ struct expected_copy_base : expected_operations_base { } 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 ::value && std::is_copy_constructible::value), bool EnableMove = (std::is_move_constructible::value && - std::is_move_constructible::value)> + std::is_move_constructible::value)> struct expected_delete_ctor_base { expected_delete_ctor_base() = default; expected_delete_ctor_base(const expected_delete_ctor_base &) = default; diff --git a/tests/constructors.cpp b/tests/constructors.cpp index 817797b..420c8bd 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -59,4 +59,55 @@ TEST_CASE("Constructors", "[constructors]") { REQUIRE(std::get<1>(e->t) == 3); } + { + tl::expected e; + REQUIRE(std::is_default_constructible::value); + REQUIRE(std::is_copy_constructible::value); + REQUIRE(std::is_trivially_copy_constructible::value); + REQUIRE(std::is_move_constructible::value); + REQUIRE(std::is_trivially_move_constructible::value); + REQUIRE(std::is_copy_assignable::value); + REQUIRE(std::is_trivially_copy_assignable::value); + REQUIRE(std::is_move_assignable::value); + REQUIRE(std::is_trivially_move_assignable::value); + } + + { + tl::expected e; + REQUIRE(std::is_default_constructible::value); + REQUIRE(std::is_copy_constructible::value); + REQUIRE(!std::is_trivially_copy_constructible::value); + REQUIRE(std::is_move_constructible::value); + REQUIRE(!std::is_trivially_move_constructible::value); + REQUIRE(std::is_copy_assignable::value); + REQUIRE(!std::is_trivially_copy_assignable::value); + REQUIRE(std::is_move_assignable::value); + REQUIRE(!std::is_trivially_move_assignable::value); + } + + { + tl::expected e; + REQUIRE(std::is_default_constructible::value); + REQUIRE(std::is_copy_constructible::value); + REQUIRE(!std::is_trivially_copy_constructible::value); + REQUIRE(std::is_move_constructible::value); + REQUIRE(!std::is_trivially_move_constructible::value); + REQUIRE(std::is_copy_assignable::value); + REQUIRE(!std::is_trivially_copy_assignable::value); + REQUIRE(std::is_move_assignable::value); + REQUIRE(!std::is_trivially_move_assignable::value); + } + + { + tl::expected e; + REQUIRE(std::is_default_constructible::value); + REQUIRE(std::is_copy_constructible::value); + REQUIRE(!std::is_trivially_copy_constructible::value); + REQUIRE(std::is_move_constructible::value); + REQUIRE(!std::is_trivially_move_constructible::value); + REQUIRE(std::is_copy_assignable::value); + REQUIRE(!std::is_trivially_copy_assignable::value); + REQUIRE(std::is_move_assignable::value); + REQUIRE(!std::is_trivially_move_assignable::value); + } } From abbd7d8ec42d41fa0ce7c5a7b98ac38153ff5dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 19:17:13 -0500 Subject: [PATCH 2/6] Fixed comments --- expected.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/expected.hpp b/expected.hpp index c2f510d..e4fa84d 100644 --- a/expected.hpp +++ b/expected.hpp @@ -590,13 +590,13 @@ struct expected_operations_base : expected_storage_base { }; // This class manages conditionally having a trivial copy constructor -// This specialization is for when T is trivially copy constructible +// This specialization is for when T and E are trivially copy constructible template struct expected_copy_base : expected_operations_base { using expected_operations_base::expected_operations_base; }; -// This specialization is for when T is not trivially copy constructible +// This specialization is for when T or E are not trivially copy constructible template struct expected_copy_base : expected_operations_base { using expected_operations_base::expected_operations_base; From 65cf9dd693e6b59a589b16905ec629ab720ac3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 19:55:35 -0500 Subject: [PATCH 3/6] Fixed missing includes --- tests/constructors.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/constructors.cpp b/tests/constructors.cpp index 420c8bd..a963a2a 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -2,6 +2,8 @@ #include "expected.hpp" #include +#include +#include struct takes_init_and_variadic { std::vector v; From 0f335690db31427a006e4b5d872dd5ef8a2ebbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 20:13:08 -0500 Subject: [PATCH 4/6] Fixed compilation on "is_trivially_*" traits on GCC4.8+ --- tests/constructors.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/tests/constructors.cpp b/tests/constructors.cpp index a963a2a..c164270 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -65,51 +65,59 @@ TEST_CASE("Constructors", "[constructors]") { tl::expected e; REQUIRE(std::is_default_constructible::value); REQUIRE(std::is_copy_constructible::value); - REQUIRE(std::is_trivially_copy_constructible::value); REQUIRE(std::is_move_constructible::value); - REQUIRE(std::is_trivially_move_constructible::value); REQUIRE(std::is_copy_assignable::value); - REQUIRE(std::is_trivially_copy_assignable::value); REQUIRE(std::is_move_assignable::value); - REQUIRE(std::is_trivially_move_assignable::value); + REQUIRE(!IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); + REQUIRE(!IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); +# if !defined(TL_EXPECTED_GCC49) + REQUIRE(!std::is_trivially_move_constructible::value); + REQUIRE(!std::is_trivially_move_assignable::value); +# endif } { tl::expected e; REQUIRE(std::is_default_constructible::value); REQUIRE(std::is_copy_constructible::value); - REQUIRE(!std::is_trivially_copy_constructible::value); REQUIRE(std::is_move_constructible::value); - REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(std::is_copy_assignable::value); - REQUIRE(!std::is_trivially_copy_assignable::value); REQUIRE(std::is_move_assignable::value); + REQUIRE(!IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); + REQUIRE(!IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); +# if !defined(TL_EXPECTED_GCC49) + REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(!std::is_trivially_move_assignable::value); +# endif } { tl::expected e; REQUIRE(std::is_default_constructible::value); REQUIRE(std::is_copy_constructible::value); - REQUIRE(!std::is_trivially_copy_constructible::value); REQUIRE(std::is_move_constructible::value); - REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(std::is_copy_assignable::value); - REQUIRE(!std::is_trivially_copy_assignable::value); REQUIRE(std::is_move_assignable::value); + REQUIRE(!IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); + REQUIRE(!IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); +# if !defined(TL_EXPECTED_GCC49) + REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(!std::is_trivially_move_assignable::value); +# endif } { tl::expected e; REQUIRE(std::is_default_constructible::value); REQUIRE(std::is_copy_constructible::value); - REQUIRE(!std::is_trivially_copy_constructible::value); REQUIRE(std::is_move_constructible::value); - REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(std::is_copy_assignable::value); - REQUIRE(!std::is_trivially_copy_assignable::value); REQUIRE(std::is_move_assignable::value); + REQUIRE(!IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); + REQUIRE(!IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); +# if !defined(TL_EXPECTED_GCC49) + REQUIRE(!std::is_trivially_move_constructible::value); REQUIRE(!std::is_trivially_move_assignable::value); +# endif } } From 5bed466a7e946b6fdfa04167913a17d9a787b791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 20:18:26 -0500 Subject: [PATCH 5/6] Fixed copy-paste error --- tests/constructors.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/constructors.cpp b/tests/constructors.cpp index c164270..ad669eb 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -68,11 +68,11 @@ TEST_CASE("Constructors", "[constructors]") { REQUIRE(std::is_move_constructible::value); REQUIRE(std::is_copy_assignable::value); REQUIRE(std::is_move_assignable::value); - REQUIRE(!IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); - REQUIRE(!IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); + REQUIRE(IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))); + REQUIRE(IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))); # if !defined(TL_EXPECTED_GCC49) - REQUIRE(!std::is_trivially_move_constructible::value); - REQUIRE(!std::is_trivially_move_assignable::value); + REQUIRE(std::is_trivially_move_constructible::value); + REQUIRE(std::is_trivially_move_assignable::value); # endif } From 6a56887068b85abcb4580dcabbd6e7a53cc25ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Alexandre=20Boissonneault?= Date: Sat, 2 Dec 2017 22:06:07 -0500 Subject: [PATCH 6/6] Fixed non-trivial copy assignment in "expected_move_assign_base" --- expected.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/expected.hpp b/expected.hpp index e4fa84d..d7e875a 100644 --- a/expected.hpp +++ b/expected.hpp @@ -710,14 +710,14 @@ struct expected_move_assign_base expected_move_assign_base(expected_move_assign_base &&rhs) = default; expected_move_assign_base & - operator=(const expected_move_assign_base &rhs) noexcept( - std::is_nothrow_move_constructible::value - &&std::is_nothrow_move_assignable::value) { - this->assign(rhs); - return *this; - } + operator=(const expected_move_assign_base &rhs) = default; expected_move_assign_base & - operator=(expected_move_assign_base &&rhs) = default; + operator=(expected_move_assign_base &&rhs) noexcept( + std::is_nothrow_move_constructible::value + &&std::is_nothrow_move_assignable::value) { + this->assign(std::move(rhs)); + return *this; + } }; // expected_delete_ctor_base will conditionally delete copy and move