Skip to content

Commit 0bb5413

Browse files
committed
meta: invalid meta_any when copying non-copyable types
1 parent e7650e2 commit 0bb5413

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,3 @@ TODO:
3535
* introduce a way to inject stl from outside too
3636
* export optional as meta_pointer like (or refine meta-pointer like detection)
3737
* redesign snapshot as a whole
38-
* meta_any::operator bool() for non-copyable types should return false after a copy

src/entt/meta/meta.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,12 @@ class meta_any {
335335
* @brief Copy constructor.
336336
* @param other The instance to copy from.
337337
*/
338-
meta_any(const meta_any &other) = default;
338+
meta_any(const meta_any &other)
339+
: storage{other.storage},
340+
ctx{other.ctx},
341+
node{(other.storage && !storage) ? nullptr : other.node},
342+
vtable{(other.storage && !storage) ? nullptr : other.vtable} {
343+
}
339344

340345
/**
341346
* @brief Move constructor.
@@ -357,10 +362,10 @@ class meta_any {
357362
*/
358363
meta_any &operator=(const meta_any &other) {
359364
if(this != &other) {
360-
storage = other.storage;
361365
ctx = other.ctx;
362-
node = other.node;
363-
vtable = other.vtable;
366+
storage = other.storage;
367+
node = (other.storage && !storage) ? nullptr : other.node;
368+
vtable = (other.storage && !storage) ? nullptr : other.vtable;
364369
}
365370

366371
return *this;

test/entt/meta/meta_any.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,3 +1601,24 @@ TEST_F(MetaAny, ForwardAsMeta) {
16011601
ASSERT_NE(any.base().data(), &value);
16021602
ASSERT_EQ(ref.base().data(), &value);
16031603
}
1604+
1605+
TEST_F(MetaAny, NonCopyableType) {
1606+
const std::unique_ptr<int> value{};
1607+
entt::meta_any any{std::in_place_type<std::unique_ptr<int>>};
1608+
entt::meta_any other = entt::forward_as_meta(value);
1609+
1610+
ASSERT_TRUE(any);
1611+
ASSERT_TRUE(other);
1612+
1613+
ASSERT_FALSE(any.assign(std::move(other)));
1614+
1615+
entt::meta_any copy{any};
1616+
1617+
ASSERT_TRUE(any);
1618+
ASSERT_FALSE(copy);
1619+
1620+
copy = any;
1621+
1622+
ASSERT_TRUE(any);
1623+
ASSERT_FALSE(copy);
1624+
}

0 commit comments

Comments
 (0)