meta: meta_any support for non-copyable types (close #336)

This commit is contained in:
Michele Caini
2019-12-25 16:10:03 +01:00
parent 7a3b7593d0
commit f17b975fb9
2 changed files with 31 additions and 6 deletions

View File

@@ -262,11 +262,6 @@ private:
*
* This class uses a technique called small buffer optimization (SBO) to get rid
* of memory allocations if possible. This should improve overall performance.
*
* @warning
* Only copy constructible types are suitable for use with this class.<br/>
* A static assertion will abort the compilation when the type isn't copy
* constructible.
*/
class meta_any {
using storage_type = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
@@ -513,7 +508,7 @@ public:
meta_any any{};
if(const auto id = internal::meta_info<Type>::resolve()->id; node && node->id == id) {
any = *static_cast<const Type *>(instance);
any = *this;
} else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([id](const auto *curr) { return curr->type()->id == id; }, node); conv) {
any = conv->conv(instance);
}

View File

@@ -123,6 +123,14 @@ struct not_comparable_type {
bool operator==(const not_comparable_type &) const = delete;
};
struct unmanageable_type {
unmanageable_type() = default;
unmanageable_type(const unmanageable_type &) = delete;
unmanageable_type(unmanageable_type &&) = delete;
unmanageable_type & operator=(const unmanageable_type &) = delete;
unmanageable_type & operator=(unmanageable_type &&) = delete;
};
bool operator!=(const not_comparable_type &, const not_comparable_type &) = delete;
struct an_abstract_type {
@@ -885,6 +893,28 @@ TEST_F(Meta, MetaAnyConstConvert) {
ASSERT_EQ(other.cast<int>(), 42);
}
TEST_F(Meta, MetaAnyUnmanageableType) {
unmanageable_type instance;
entt::meta_any any{std::ref(instance)};
entt::meta_any other = any;
std::swap(any, other);
ASSERT_TRUE(any);
ASSERT_TRUE(other);
ASSERT_EQ(any.type(), entt::resolve<unmanageable_type>());
ASSERT_NE(any.data(), nullptr);
ASSERT_EQ(any.try_cast<int>(), nullptr);
ASSERT_NE(any.try_cast<unmanageable_type>(), nullptr);
ASSERT_TRUE(any.convert<unmanageable_type>());
ASSERT_FALSE(any.convert<int>());
ASSERT_TRUE(std::as_const(any).convert<unmanageable_type>());
ASSERT_FALSE(std::as_const(any).convert<int>());
}
TEST_F(Meta, MetaProp) {
auto prop = entt::resolve<char>().prop(props::prop_int);