meta: review

This commit is contained in:
Michele Caini
2019-03-01 17:07:08 +01:00
parent 1ae436cb08
commit 78c171e0c2
4 changed files with 22 additions and 36 deletions

View File

@@ -63,7 +63,7 @@ It can be used to extend the reflected type and add the following:
* _Destructors_. Free functions can be set as destructors of reflected types.
The purpose is to give users the ability to free up resources that require
special treatment before an object is actually destroyed.<br/>
special treatment before an object is actually destroyed.<br/>
Use the `dtor` member function for this purpose:
```cpp

View File

@@ -272,7 +272,7 @@ public:
* The signature of the function should identical to the following:
*
* @code{.cpp}
* void(Type &);
* void(Type *);
* @endcode
*
* From a client's point of view, nothing changes if the destructor of a
@@ -283,14 +283,14 @@ public:
*/
template<auto *Func>
meta_factory dtor() ENTT_NOEXCEPT {
static_assert(std::is_invocable_v<decltype(Func), Type &>);
static_assert(std::is_invocable_v<decltype(Func), Type *>);
auto * const type = internal::meta_info<Type>::resolve();
static internal::meta_dtor_node node{
type,
[](meta_handle handle) {
return handle.type() == internal::meta_info<Type>::resolve()->meta()
? ((*Func)(*static_cast<Type *>(handle.data())), true)
? ((*Func)(static_cast<Type *>(handle.data())), true)
: false;
},
[]() -> meta_dtor {
@@ -379,9 +379,10 @@ public:
*
* Setters and getters can be either free functions, member functions or a
* mix of them.<br/>
* In case of free functions, setters and getters must accept an instance of
* the parent type as their first argument. A setter has then an extra
* argument of a type convertible to that of the parameter to set.<br/>
* In case of free functions, setters and getters must accept a pointer to
* an instance of the parent type as their first argument. A setter has then
* an extra argument of a type convertible to that of the parameter to
* set.<br/>
* In case of member functions, getters have no arguments at all, while
* setters has an argument of a type convertible to that of the parameter to
* set.
@@ -396,8 +397,8 @@ public:
template<auto Setter, auto Getter, typename... Property>
meta_factory data(const char *str, Property &&... property) ENTT_NOEXCEPT {
using owner_type = std::tuple<std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>;
using data_type = std::invoke_result_t<decltype(Getter), Type &>;
static_assert(std::is_invocable_v<decltype(Setter), Type &, data_type>);
using data_type = std::invoke_result_t<decltype(Getter), Type *>;
static_assert(std::is_invocable_v<decltype(Setter), Type *, data_type>);
auto * const type = internal::meta_info<Type>::resolve();
static internal::meta_data_node node{

View File

@@ -656,9 +656,6 @@ public:
: meta_handle{0, std::forward<Type>(instance)}
{}
/*! @brief Default destructor. */
~meta_handle() ENTT_NOEXCEPT = default;
/**
* @brief Returns the meta type of the underlying object.
* @return The meta type of the underlying object, if any.
@@ -2042,17 +2039,12 @@ bool setter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any &any)
} else if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>> || std::is_member_function_pointer_v<decltype(Data)>) {
using helper_type = meta_function_helper<std::integral_constant<decltype(Data), Data>>;
using data_type = std::decay_t<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>);
accepted = any.can_cast<data_type>() || any.convert<data_type>();
auto *clazz = handle.try_cast<Type>();
if(accepted && clazz) {
if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>>) {
static_assert(std::is_invocable_v<decltype(Data), Type &, data_type>);
Data(*clazz, any.cast<data_type>());
} else if constexpr(std::is_member_function_pointer_v<decltype(Data)>) {
static_assert(std::is_invocable_v<decltype(Data), Type *, data_type>);
(clazz->*Data)(any.cast<data_type>());
}
std::invoke(Data, clazz, any.cast<data_type>());
}
} else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
using data_type = std::decay_t<decltype(std::declval<Type>().*Data)>;
@@ -2061,7 +2053,7 @@ bool setter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any &any)
auto *clazz = handle.try_cast<Type>();
if(accepted && clazz) {
clazz->*Data = any.cast<data_type>();
std::invoke(Data, clazz) = any.cast<data_type>();
}
} else {
static_assert(std::is_pointer_v<decltype(Data)>);
@@ -2080,16 +2072,9 @@ bool setter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any &any)
template<typename Type, auto Data>
inline meta_any getter([[maybe_unused]] meta_handle handle) {
if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>> || std::is_member_pointer_v<decltype(Data)>) {
static_assert(std::is_invocable_v<decltype(Data), Type &>);
static_assert(std::is_invocable_v<decltype(Data), Type *>);
auto *clazz = handle.try_cast<Type>();
if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>>) {
return clazz ? meta_any{Data(*clazz)} : meta_any{};
} else if constexpr(std::is_member_function_pointer_v<decltype(Data)>) {
return clazz ? meta_any{(clazz->*Data)()} : meta_any{};
} else /* if constexpr(std::is_member_object_pointer_v<decltype(Data)>) */ {
return clazz ? meta_any{clazz->*Data} : meta_any{};
}
return clazz ? std::invoke(Data, clazz) : meta_any{};
} else {
static_assert(std::is_pointer_v<decltype(Data)>);
return meta_any{*Data};
@@ -2107,9 +2092,9 @@ invoke(const meta_handle &, meta_any *args, std::index_sequence<Indexes...>) {
|| (args+Indexes)->convert<typename helper_type::template arg_type<Indexes>>()) && ...))
{
if constexpr(std::is_void_v<typename helper_type::return_type>) {
(*Func)((args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...);
std::invoke(Func, (args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...);
} else {
any = meta_any{(*Func)((args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...)};
any = meta_any{std::invoke(Func, (args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...)};
}
}
@@ -2129,9 +2114,9 @@ invoke(meta_handle &handle, meta_any *args, std::index_sequence<Indexes...>) {
|| (args+Indexes)->convert<typename helper_type::template arg_type<Indexes>>()) && ...))
{
if constexpr(std::is_void_v<typename helper_type::return_type>) {
(clazz->*Member)((args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...);
std::invoke(Member, clazz, (args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...);
} else {
any = meta_any{(clazz->*Member)((args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...)};
any = meta_any{std::invoke(Member, clazz, (args+Indexes)->cast<typename helper_type::template arg_type<Indexes>>()...)};
}
}

View File

@@ -13,7 +13,7 @@ enum class properties {
struct empty_type {
virtual ~empty_type() = default;
static void destroy(empty_type &instance) {
static void destroy(empty_type *) {
++counter;
}
@@ -89,8 +89,8 @@ struct setter_getter_type {
int setter_with_ref(const int &value) { return this->value = value; }
const int & getter_with_ref() { return value; }
static int static_setter(setter_getter_type &type, int value) { return type.value = value; }
static int static_getter(const setter_getter_type &type) { return type.value; }
static int static_setter(setter_getter_type *type, int value) { return type->value = value; }
static int static_getter(const setter_getter_type *type) { return type->value; }
};
struct not_comparable_type {