diff --git a/tests/issues.cpp b/tests/issues.cpp index 241a0df..b43edaa 100644 --- a/tests/issues.cpp +++ b/tests/issues.cpp @@ -30,3 +30,16 @@ TEST_CASE("Issue 26", "[issues.26]") { tl::expected exp = tl::expected(tl::unexpect, 0); REQUIRE(!exp.has_value()); } + +struct foo { + foo() = default; + foo(foo&) = delete; + foo(foo&&) {}; +}; + +TEST_CASE("Issue 29", "[issues.29]") { + std::vector v; + v.emplace_back(); + tl::expected, int> ov = std::move(v); + REQUIRE(ov->size() == 1); +} diff --git a/tl/expected.hpp b/tl/expected.hpp index adcf766..47ceb8a 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -70,6 +70,29 @@ /// \exclude #define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible + +// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector +// for non-copyable types +#elif (defined(__GNUC__) && __GNUC__ < 8 && \ + !defined(__clang__)) +#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +namespace tl { + namespace detail { + template + struct is_trivially_copy_constructible : std::is_trivially_copy_constructible{}; + template + struct is_trivially_copy_constructible> + : std::is_trivially_copy_constructible{}; + } +} +#endif + +#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + tl::detail::is_trivially_copy_constructible +#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::is_trivially_copy_assignable +#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible #else /// \exclude #define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \