meta: arrays are no longer indexable via meta_type::set/get
This commit is contained in:
@@ -76,59 +76,35 @@ template<typename Type, typename... Args, std::size_t... Indexes>
|
||||
|
||||
|
||||
template<typename Type, auto Data>
|
||||
[[nodiscard]] bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index, [[maybe_unused]] meta_any value) {
|
||||
[[nodiscard]] bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any value) {
|
||||
bool accepted = false;
|
||||
|
||||
if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>> || std::is_member_function_pointer_v<decltype(Data)>) {
|
||||
using helper_type = meta_function_helper_t<decltype(Data)>;
|
||||
using data_type = std::tuple_element_t<!std::is_member_function_pointer_v<decltype(Data)>, typename helper_type::args_type>;
|
||||
static_assert(std::is_invocable_v<decltype(Data), Type &, data_type>, "Invalid function or member function");
|
||||
auto * const clazz = instance.try_cast<Type>();
|
||||
auto * const direct = value.try_cast<data_type>();
|
||||
|
||||
if(clazz && (direct || value.convert<data_type>())) {
|
||||
std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
if(auto * const clazz = instance.try_cast<Type>(); clazz) {
|
||||
if(auto * const direct = value.try_cast<data_type>(); direct || value.convert<data_type>()) {
|
||||
std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
}
|
||||
}
|
||||
} else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
|
||||
using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
|
||||
static_assert(std::is_invocable_v<decltype(Data), Type *>, "Invalid data member");
|
||||
auto * const clazz = instance.try_cast<Type>();
|
||||
|
||||
if constexpr(std::is_array_v<data_type>) {
|
||||
using underlying_type = std::remove_extent_t<data_type>;
|
||||
auto * const direct = value.try_cast<underlying_type>();
|
||||
auto * const idx = index.try_cast<std::size_t>();
|
||||
|
||||
if(clazz && idx && (direct || value.convert<underlying_type>())) {
|
||||
std::invoke(Data, clazz)[*idx] = direct ? *direct : value.cast<underlying_type>();
|
||||
accepted = true;
|
||||
}
|
||||
} else {
|
||||
auto * const direct = value.try_cast<data_type>();
|
||||
|
||||
if(clazz && (direct || value.convert<data_type>())) {
|
||||
std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
if constexpr(!std::is_array_v<data_type>) {
|
||||
if(auto * const clazz = instance.try_cast<Type>(); clazz) {
|
||||
if(auto * const direct = value.try_cast<data_type>(); direct || value.convert<data_type>()) {
|
||||
std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
static_assert(std::is_pointer_v<decltype(Data)>, "Invalid pointer to data type");
|
||||
using data_type = std::remove_cv_t<std::remove_reference_t<decltype(*Data)>>;
|
||||
|
||||
if constexpr(std::is_array_v<data_type>) {
|
||||
using underlying_type = std::remove_extent_t<data_type>;
|
||||
auto * const direct = value.try_cast<underlying_type>();
|
||||
auto * const idx = index.try_cast<std::size_t>();
|
||||
|
||||
if(idx && (direct || value.convert<underlying_type>())) {
|
||||
(*Data)[*idx] = (direct ? *direct : value.cast<underlying_type>());
|
||||
accepted = true;
|
||||
}
|
||||
} else {
|
||||
auto * const direct = value.try_cast<data_type>();
|
||||
|
||||
if(direct || value.convert<data_type>()) {
|
||||
if constexpr(!std::is_array_v<data_type>) {
|
||||
if(auto * const direct = value.try_cast<data_type>(); direct || value.convert<data_type>()) {
|
||||
*Data = (direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
}
|
||||
@@ -140,7 +116,7 @@ template<typename Type, auto Data>
|
||||
|
||||
|
||||
template<typename Type, auto Data, typename Policy>
|
||||
[[nodiscard]] meta_any getter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index) {
|
||||
[[nodiscard]] meta_any getter([[maybe_unused]] meta_any instance) {
|
||||
auto dispatch = [](auto &&value) {
|
||||
if constexpr(std::is_same_v<Policy, as_void_t>) {
|
||||
return meta_any{std::in_place_type<void>, std::forward<decltype(value)>(value)};
|
||||
@@ -153,24 +129,18 @@ template<typename Type, auto Data, typename Policy>
|
||||
};
|
||||
|
||||
if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>> || std::is_member_function_pointer_v<decltype(Data)>) {
|
||||
static_assert(std::is_invocable_v<decltype(Data), Type &>, "Invalid function or member function");
|
||||
auto * const clazz = instance.try_cast<Type>();
|
||||
return clazz ? dispatch(std::invoke(Data, *clazz)) : meta_any{};
|
||||
} else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
|
||||
using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
|
||||
static_assert(std::is_invocable_v<decltype(Data), Type *>, "Invalid data member");
|
||||
auto * const clazz = instance.try_cast<Type>();
|
||||
|
||||
if constexpr(std::is_array_v<data_type>) {
|
||||
auto * const idx = index.try_cast<std::size_t>();
|
||||
return (clazz && idx) ? dispatch(std::invoke(Data, clazz)[*idx]) : meta_any{};
|
||||
if constexpr(std::is_array_v<std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>>) {
|
||||
return meta_any{};
|
||||
} else {
|
||||
auto * const clazz = instance.try_cast<Type>();
|
||||
return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{};
|
||||
}
|
||||
} else if constexpr(std::is_pointer_v<std::decay_t<decltype(Data)>>) {
|
||||
if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
|
||||
auto * const idx = index.try_cast<std::size_t>();
|
||||
return idx ? dispatch((*Data)[*idx]) : meta_any{};
|
||||
return meta_any{};
|
||||
} else {
|
||||
return dispatch(*Data);
|
||||
}
|
||||
@@ -666,7 +636,7 @@ public:
|
||||
false,
|
||||
&internal::meta_info<underlying_type>::resolve,
|
||||
[]() -> decltype(internal::meta_data_node::set) {
|
||||
if constexpr(std::is_same_v<decltype(Setter), std::nullptr_t> || (std::is_member_object_pointer_v<decltype(Setter)> && std::is_const_v<underlying_type>)) {
|
||||
if constexpr(std::is_same_v<decltype(Setter), std::nullptr_t> || (std::is_member_object_pointer_v<decltype(Setter)> && std::is_const_v<underlying_type>)) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return &internal::setter<Type, Setter>;
|
||||
|
||||
@@ -77,8 +77,8 @@ struct meta_data_node {
|
||||
meta_prop_node * prop;
|
||||
const bool is_static;
|
||||
meta_type_node *(* const type)() ENTT_NOEXCEPT;
|
||||
bool(* const set)(meta_any, meta_any, meta_any);
|
||||
meta_any(* const get)(meta_any, meta_any);
|
||||
bool(* const set)(meta_any, meta_any);
|
||||
meta_any(* const get)(meta_any);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -711,28 +711,7 @@ struct meta_data {
|
||||
*/
|
||||
template<typename Type>
|
||||
bool set(meta_handle instance, Type &&value) const {
|
||||
return node->set && node->set(*instance, {}, std::forward<Type>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the i-th element of a given array.
|
||||
*
|
||||
* It must be possible to cast the instance to the parent type of the meta
|
||||
* data. Otherwise, invoking the setter results in an undefined
|
||||
* behavior.<br/>
|
||||
* The type of the value must be such that a cast or conversion to the array
|
||||
* type is possible. Otherwise, invoking the setter does nothing.
|
||||
*
|
||||
* @tparam Type Type of value to assign.
|
||||
* @param instance An opaque instance of the underlying type.
|
||||
* @param index Position of the underlying element to set.
|
||||
* @param value Parameter to use to set the underlying element.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
template<typename Type>
|
||||
bool set(meta_handle instance, std::size_t index, Type &&value) const {
|
||||
ENTT_ASSERT(index < node->type()->extent);
|
||||
return node->set && node->set(*instance, index, std::forward<Type>(value));
|
||||
return node->set && node->set(*instance, std::forward<Type>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -745,22 +724,7 @@ struct meta_data {
|
||||
* @return A meta any containing the value of the underlying variable.
|
||||
*/
|
||||
[[nodiscard]] meta_any get(meta_handle instance) const {
|
||||
return node->get(*instance, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the i-th element of a given array.
|
||||
*
|
||||
* It must be possible to cast the instance to the parent type of the meta
|
||||
* data. Otherwise, invoking the getter results in an undefined behavior.
|
||||
*
|
||||
* @param instance An opaque instance of the underlying type.
|
||||
* @param index Position of the underlying element to get.
|
||||
* @return A meta any containing the value of the underlying element.
|
||||
*/
|
||||
[[nodiscard]] meta_any get(meta_handle instance, std::size_t index) const {
|
||||
ENTT_ASSERT(index < node->type()->extent);
|
||||
return node->get(*instance, index);
|
||||
return node->get(*instance);
|
||||
}
|
||||
|
||||
/*! @copydoc meta_ctor::prop */
|
||||
|
||||
@@ -54,7 +54,7 @@ struct setter_getter_t {
|
||||
|
||||
struct array_t {
|
||||
static inline int global[3];
|
||||
int local[3];
|
||||
int local[5];
|
||||
};
|
||||
|
||||
enum class property_t {
|
||||
@@ -347,10 +347,6 @@ TEST_F(MetaData, SetterGetterReadOnlyDataMember) {
|
||||
TEST_F(MetaData, ArrayStatic) {
|
||||
auto data = entt::resolve<array_t>().data("global"_hs);
|
||||
|
||||
array_t::global[0] = 3;
|
||||
array_t::global[1] = 5;
|
||||
array_t::global[2] = 7;
|
||||
|
||||
ASSERT_TRUE(data);
|
||||
ASSERT_EQ(data.parent(), entt::resolve_id("array"_hs));
|
||||
ASSERT_EQ(data.type(), entt::resolve<int[3]>());
|
||||
@@ -359,46 +355,22 @@ TEST_F(MetaData, ArrayStatic) {
|
||||
ASSERT_TRUE(data.is_static());
|
||||
ASSERT_TRUE(data.type().is_array());
|
||||
ASSERT_EQ(data.type().extent(), 3);
|
||||
ASSERT_EQ(data.get({}, 0).cast<int>(), 3);
|
||||
ASSERT_EQ(data.get({}, 1).cast<int>(), 5);
|
||||
ASSERT_EQ(data.get({}, 2).cast<int>(), 7);
|
||||
ASSERT_FALSE(data.set({}, 0, 'c'));
|
||||
ASSERT_EQ(data.get({}, 0).cast<int>(), 3);
|
||||
ASSERT_TRUE(data.set({}, 0, data.get({}, 0).cast<int>()+2));
|
||||
ASSERT_TRUE(data.set({}, 1, data.get({}, 1).cast<int>()+2));
|
||||
ASSERT_TRUE(data.set({}, 2, data.get({}, 2).cast<int>()+2));
|
||||
ASSERT_EQ(data.get({}, 0).cast<int>(), 5);
|
||||
ASSERT_EQ(data.get({}, 1).cast<int>(), 7);
|
||||
ASSERT_EQ(data.get({}, 2).cast<int>(), 9);
|
||||
ASSERT_FALSE(data.get({}));
|
||||
}
|
||||
|
||||
TEST_F(MetaData, Array) {
|
||||
auto data = entt::resolve<array_t>().data("local"_hs);
|
||||
array_t instance;
|
||||
|
||||
instance.local[0] = 3;
|
||||
instance.local[1] = 5;
|
||||
instance.local[2] = 7;
|
||||
|
||||
ASSERT_TRUE(data);
|
||||
ASSERT_EQ(data.parent(), entt::resolve_id("array"_hs));
|
||||
ASSERT_EQ(data.type(), entt::resolve<int[3]>());
|
||||
ASSERT_EQ(data.type(), entt::resolve<int[5]>());
|
||||
ASSERT_EQ(data.id(), "local"_hs);
|
||||
ASSERT_FALSE(data.is_const());
|
||||
ASSERT_FALSE(data.is_static());
|
||||
ASSERT_TRUE(data.type().is_array());
|
||||
ASSERT_EQ(data.type().extent(), 3);
|
||||
ASSERT_EQ(data.get(instance, 0).cast<int>(), 3);
|
||||
ASSERT_EQ(data.get(instance, 1).cast<int>(), 5);
|
||||
ASSERT_EQ(data.get(instance, 2).cast<int>(), 7);
|
||||
ASSERT_FALSE(data.set(instance, 0, 'c'));
|
||||
ASSERT_EQ(data.get(instance, 0).cast<int>(), 3);
|
||||
ASSERT_TRUE(data.set(instance, 0, data.get(instance, 0).cast<int>()+2));
|
||||
ASSERT_TRUE(data.set(instance, 1, data.get(instance, 1).cast<int>()+2));
|
||||
ASSERT_TRUE(data.set(instance, 2, data.get(instance, 2).cast<int>()+2));
|
||||
ASSERT_EQ(data.get(instance, 0).cast<int>(), 5);
|
||||
ASSERT_EQ(data.get(instance, 1).cast<int>(), 7);
|
||||
ASSERT_EQ(data.get(instance, 2).cast<int>(), 9);
|
||||
ASSERT_EQ(data.type().extent(), 5);
|
||||
ASSERT_FALSE(data.get(instance));
|
||||
}
|
||||
|
||||
TEST_F(MetaData, AsVoid) {
|
||||
|
||||
Reference in New Issue
Block a user