From 9df8d1be3993a28bb78e8e0b3f8552ee57416a7f Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 14 Aug 2018 09:56:31 +0100 Subject: [PATCH] Support std::vector of non-copyable types --- tests/constructors.cpp | 12 ++++++++++++ tl/optional.hpp | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/constructors.cpp b/tests/constructors.cpp index a9a9c44..fc87a97 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -1,5 +1,12 @@ #include "catch.hpp" #include "optional.hpp" +#include + +struct foo { + foo() = default; + foo(foo&) = delete; + foo(foo&&) {}; +}; TEST_CASE("Constructors", "[constructors]") { tl::optional o1; @@ -47,4 +54,9 @@ TEST_CASE("Constructors", "[constructors]") { REQUIRE(oo); REQUIRE(*oo == 42); } + + std::vector v; + v.emplace_back(); + tl::optional> ov = std::move(v); + REQUIRE(ov->size() == 1); } diff --git a/tl/optional.hpp b/tl/optional.hpp index 0615901..c60c358 100644 --- a/tl/optional.hpp +++ b/tl/optional.hpp @@ -55,6 +55,26 @@ // This one will be different for GCC 5.7 if it's ever supported #define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible::value + +// 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__)) +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{}; + } +} + +#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + tl::detail::is_trivially_copy_constructible::value +#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::is_trivially_copy_assignable::value +#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible::value #else #define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::is_trivially_copy_constructible::value