meta_any: fixed #180
This commit is contained in:
@@ -379,9 +379,7 @@ public:
|
||||
compare_fn = &compare<actual_type>;
|
||||
|
||||
if constexpr(sizeof(actual_type) <= sizeof(void *)) {
|
||||
new (&storage) actual_type{std::forward<Type>(type)};
|
||||
instance = &storage;
|
||||
|
||||
instance = new (&storage) actual_type{std::forward<Type>(type)};
|
||||
destroy_fn = &destroy_storage<actual_type>;
|
||||
copy_fn = ©_storage<actual_type>;
|
||||
} else {
|
||||
@@ -440,7 +438,7 @@ public:
|
||||
* @return This meta any object.
|
||||
*/
|
||||
meta_any & operator=(meta_any other) {
|
||||
swap(*this, other);
|
||||
swap(other, *this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -550,7 +548,7 @@ public:
|
||||
auto any = std::as_const(*this).convert<Type>();
|
||||
|
||||
if(any) {
|
||||
std::swap(*this, any);
|
||||
std::swap(any, *this);
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
@@ -584,20 +582,28 @@ public:
|
||||
friend void swap(meta_any &lhs, meta_any &rhs) {
|
||||
using std::swap;
|
||||
|
||||
std::swap(lhs.storage, rhs.storage);
|
||||
std::swap(lhs.instance, rhs.instance);
|
||||
std::swap(lhs.destroy_fn, rhs.destroy_fn);
|
||||
if(lhs && rhs) {
|
||||
storage_type buffer;
|
||||
void *tmp = lhs.copy_fn(buffer, lhs.instance);
|
||||
lhs.destroy_fn(lhs.storage);
|
||||
lhs.instance = rhs.copy_fn(lhs.storage, rhs.instance);
|
||||
rhs.destroy_fn(rhs.storage);
|
||||
rhs.instance = lhs.copy_fn(rhs.storage, tmp);
|
||||
lhs.destroy_fn(buffer);
|
||||
} else if(lhs) {
|
||||
rhs.instance = lhs.copy_fn(rhs.storage, lhs.instance);
|
||||
lhs.destroy_fn(lhs.storage);
|
||||
lhs.instance = nullptr;
|
||||
} else if(rhs) {
|
||||
lhs.instance = rhs.copy_fn(lhs.storage, rhs.instance);
|
||||
rhs.destroy_fn(rhs.storage);
|
||||
rhs.instance = nullptr;
|
||||
}
|
||||
|
||||
std::swap(lhs.node, rhs.node);
|
||||
std::swap(lhs.destroy_fn, rhs.destroy_fn);
|
||||
std::swap(lhs.compare_fn, rhs.compare_fn);
|
||||
std::swap(lhs.copy_fn, rhs.copy_fn);
|
||||
|
||||
if(lhs.instance == &rhs.storage) {
|
||||
lhs.instance = &lhs.storage;
|
||||
}
|
||||
|
||||
if(rhs.instance == &lhs.storage) {
|
||||
rhs.instance = &rhs.storage;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -367,15 +367,13 @@ TEST_F(Meta, MetaAnyNoSBOMoveAssignment) {
|
||||
|
||||
TEST_F(Meta, MetaAnySBODestruction) {
|
||||
ASSERT_EQ(empty_type::counter, 0);
|
||||
entt::meta_any any{empty_type{}};
|
||||
any = {};
|
||||
{ entt::meta_any any{empty_type{}}; }
|
||||
ASSERT_EQ(empty_type::counter, 1);
|
||||
}
|
||||
|
||||
TEST_F(Meta, MetaAnyNoSBODestruction) {
|
||||
ASSERT_EQ(fat_type::counter, 0);
|
||||
entt::meta_any any{fat_type{}};
|
||||
any = {};
|
||||
{ entt::meta_any any{fat_type{}}; }
|
||||
ASSERT_EQ(fat_type::counter, 1);
|
||||
}
|
||||
|
||||
@@ -416,6 +414,37 @@ TEST_F(Meta, MetaAnySBOWithNoSBOSwap) {
|
||||
ASSERT_EQ(rhs.cast<fat_type>().bar, &value);
|
||||
}
|
||||
|
||||
TEST_F(Meta, MetaAnySBOWithEmptySwap) {
|
||||
entt::meta_any lhs{'c'};
|
||||
entt::meta_any rhs{};
|
||||
|
||||
std::swap(lhs, rhs);
|
||||
|
||||
ASSERT_FALSE(lhs);
|
||||
ASSERT_TRUE(rhs.can_cast<char>());
|
||||
ASSERT_EQ(rhs.cast<char>(), 'c');
|
||||
|
||||
std::swap(lhs, rhs);
|
||||
|
||||
ASSERT_FALSE(rhs);
|
||||
ASSERT_TRUE(lhs.can_cast<char>());
|
||||
ASSERT_EQ(lhs.cast<char>(), 'c');
|
||||
}
|
||||
|
||||
TEST_F(Meta, MetaAnyNoSBOWithEmptySwap) {
|
||||
int i;
|
||||
entt::meta_any lhs{fat_type{&i}};
|
||||
entt::meta_any rhs{};
|
||||
|
||||
std::swap(lhs, rhs);
|
||||
|
||||
ASSERT_EQ(rhs.cast<fat_type>().bar, &i);
|
||||
|
||||
std::swap(lhs, rhs);
|
||||
|
||||
ASSERT_EQ(lhs.cast<fat_type>().bar, &i);
|
||||
}
|
||||
|
||||
TEST_F(Meta, MetaAnyComparable) {
|
||||
entt::meta_any any{'c'};
|
||||
|
||||
@@ -1283,14 +1312,12 @@ TEST_F(Meta, MetaTypeConstructMetaAnyArgs) {
|
||||
ASSERT_EQ(any.cast<derived_type>().c, 'c');
|
||||
}
|
||||
|
||||
|
||||
TEST_F(Meta, MetaTypeConstructInvalidArgs) {
|
||||
auto type = entt::resolve<derived_type>();
|
||||
auto any = type.construct(entt::meta_any{base_type{}}, entt::meta_any{'c'}, entt::meta_any{42});
|
||||
ASSERT_FALSE(any);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(Meta, MetaTypeConstructCastAndConvert) {
|
||||
auto type = entt::resolve<derived_type>();
|
||||
auto any = type.construct(entt::meta_any{derived_type{}}, entt::meta_any{42.}, entt::meta_any{'c'});
|
||||
@@ -1301,7 +1328,6 @@ TEST_F(Meta, MetaTypeConstructCastAndConvert) {
|
||||
ASSERT_EQ(any.cast<derived_type>().c, 'c');
|
||||
}
|
||||
|
||||
|
||||
TEST_F(Meta, MetaTypeDestroyDtor) {
|
||||
auto type = entt::resolve<empty_type>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user