meta: context aware copy/move ctor for meta_any

This commit is contained in:
Michele Caini
2022-10-14 08:45:25 +02:00
parent 82bc2e1fe4
commit 11c1e23a91
4 changed files with 59 additions and 1 deletions

1
TODO
View File

@@ -12,6 +12,7 @@ DOC:
* update entity doc when the storage based model is in place
TODO (high prio):
* remove_const_t vs remove_cv_t
* remove the static storage from the const assure in the registry
WIP:

View File

@@ -259,10 +259,32 @@ public:
* @param area The context from which to search for meta types.
* @param value An instance of an object to use to initialize the wrapper.
*/
template<typename Type>
template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
meta_any(const meta_ctx &area, Type &&value)
: meta_any{area, std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
/**
* @brief Context aware copy constructor.
* @param area The context from which to search for meta types.
* @param other The instance to copy from.
*/
meta_any(const meta_ctx &area, const meta_any &other)
: meta_any{other} {
ctx = &area;
node = node.resolve ? node.resolve(internal::meta_context::from(*ctx)) : node;
}
/**
* @brief Context aware move constructor.
* @param area The context from which to search for meta types.
* @param other The instance to move from.
*/
meta_any(const meta_ctx &area, meta_any &&other)
: meta_any{std::move(other)} {
ctx = &area;
node = node.resolve ? node.resolve(internal::meta_context::from(*ctx)) : node;
}
/**
* @brief Copy constructor.
* @param other The instance to copy from.

View File

@@ -121,6 +121,7 @@ struct meta_type_node {
id_type id{};
meta_traits traits{meta_traits::is_none};
size_type size_of{0u};
meta_type_node (*resolve)(const meta_context &) noexcept {};
meta_type_node (*remove_pointer)(const meta_context &) noexcept {};
meta_any (*default_constructor)(const meta_ctx &){};
double (*conversion_helper)(void *, const void *){};
@@ -184,6 +185,7 @@ template<typename Type>
| (is_complete_v<meta_sequence_container_traits<Type>> ? meta_traits::is_meta_sequence_container : meta_traits::is_none)
| (is_complete_v<meta_associative_container_traits<Type>> ? meta_traits::is_meta_associative_container : meta_traits::is_none),
size_of_v<Type>,
&resolve<Type>,
&resolve<std::remove_cv_t<std::remove_pointer_t<Type>>>};
if constexpr(std::is_default_constructible_v<Type>) {

View File

@@ -77,6 +77,39 @@ TEST_F(MetaUtility, MetaDispatch) {
ASSERT_EQ(as_cref.cast<int>(), 42);
}
TEST_F(MetaUtility, MetaDispatchMetaAny) {
entt::meta_any any{42};
auto from_any = entt::meta_dispatch(any);
auto from_const_any = entt::meta_dispatch(std::as_const(any));
ASSERT_EQ(from_any.type(), entt::resolve<int>());
ASSERT_EQ(from_const_any.type(), entt::resolve<int>());
ASSERT_NE(from_any.try_cast<int>(), nullptr);
ASSERT_NE(from_const_any.try_cast<int>(), nullptr);
ASSERT_EQ(from_any.cast<int>(), 42);
ASSERT_EQ(from_const_any.cast<int>(), 42);
}
TEST_F(MetaUtility, MetaDispatchMetaAnyAsRef) {
entt::meta_any any{42};
auto from_any = entt::meta_dispatch(any.as_ref());
auto from_const_any = entt::meta_dispatch(std::as_const(any).as_ref());
ASSERT_EQ(from_any.type(), entt::resolve<int>());
ASSERT_EQ(from_const_any.type(), entt::resolve<int>());
ASSERT_NE(from_any.try_cast<int>(), nullptr);
ASSERT_EQ(from_const_any.try_cast<int>(), nullptr);
ASSERT_NE(from_const_any.try_cast<const int>(), nullptr);
ASSERT_EQ(from_any.cast<int>(), 42);
ASSERT_EQ(from_const_any.cast<int>(), 42);
}
TEST_F(MetaUtility, MetaArg) {
ASSERT_EQ((entt::meta_arg<entt::type_list<int, char>>(0u)), entt::resolve<int>());
ASSERT_EQ((entt::meta_arg<entt::type_list<int, char>>(1u)), entt::resolve<char>());