meta: revert automatic policy (too convenient a feature)
This commit is contained in:
@@ -169,6 +169,7 @@ if(ENTT_INCLUDE_HEADERS)
|
||||
meta/meta.hpp
|
||||
meta/node.hpp
|
||||
meta/pointer.hpp
|
||||
meta/policy.hpp
|
||||
meta/range.hpp
|
||||
meta/resolve.hpp
|
||||
meta/template.hpp
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace entt {}
|
||||
#include "meta/meta.hpp"
|
||||
#include "meta/node.hpp"
|
||||
#include "meta/pointer.hpp"
|
||||
#include "meta/policy.hpp"
|
||||
#include "meta/range.hpp"
|
||||
#include "meta/resolve.hpp"
|
||||
#include "meta/template.hpp"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "fwd.hpp"
|
||||
#include "meta.hpp"
|
||||
#include "node.hpp"
|
||||
#include "policy.hpp"
|
||||
#include "range.hpp"
|
||||
#include "resolve.hpp"
|
||||
#include "utility.hpp"
|
||||
@@ -251,13 +252,15 @@ public:
|
||||
* type is a built-in one or not.
|
||||
*
|
||||
* @tparam Candidate The actual function to use as a constructor.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @return A meta factory for the parent type.
|
||||
*/
|
||||
template<auto Candidate>
|
||||
template<auto Candidate, typename Policy = as_is_t>
|
||||
meta_factory ctor() noexcept {
|
||||
using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
|
||||
static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
|
||||
static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>, Type>, "The function doesn't return an object of the required type");
|
||||
base_type::insert_or_assign(internal::meta_ctor_node{type_id<typename descriptor::args_type>().hash(), descriptor::args_type::size, &meta_arg<typename descriptor::args_type>, &meta_construct<Type, Candidate>});
|
||||
base_type::insert_or_assign(internal::meta_ctor_node{type_id<typename descriptor::args_type>().hash(), descriptor::args_type::size, &meta_arg<typename descriptor::args_type>, &meta_construct<Type, Candidate, Policy>});
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -285,12 +288,13 @@ public:
|
||||
/**
|
||||
* @brief Assigns a meta data to a meta type.
|
||||
* @tparam Data The actual variable to attach to the meta type.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param name A custom unique identifier as a **string literal**.
|
||||
* @return A meta factory for the given type.
|
||||
*/
|
||||
template<auto Data>
|
||||
template<auto Data, typename Policy = as_is_t>
|
||||
meta_factory data(const char *name) noexcept {
|
||||
return data<Data>(entt::hashed_string::value(name), name);
|
||||
return data<Data, Policy>(entt::hashed_string::value(name), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,14 +306,16 @@ public:
|
||||
* reflected object will appear as if they were part of the type itself.
|
||||
*
|
||||
* @tparam Data The actual variable to attach to the meta type.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param id Unique identifier.
|
||||
* @param name An optional name for the meta data as a **string literal**.
|
||||
* @return A meta factory for the parent type.
|
||||
*/
|
||||
template<auto Data>
|
||||
template<auto Data, typename Policy = as_is_t>
|
||||
meta_factory data(const id_type id, const char *name = nullptr) noexcept {
|
||||
if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
|
||||
using data_type = std::invoke_result_t<decltype(Data), Type &>;
|
||||
static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
|
||||
|
||||
base_type::data(
|
||||
internal::meta_data_node{
|
||||
@@ -321,10 +327,16 @@ public:
|
||||
&internal::resolve<std::remove_cv_t<std::remove_reference_t<data_type>>>,
|
||||
&meta_arg<type_list<std::remove_cv_t<std::remove_reference_t<data_type>>>>,
|
||||
&meta_setter<Type, Data>,
|
||||
&meta_getter<Type, Data>});
|
||||
&meta_getter<Type, Data, Policy>});
|
||||
} else {
|
||||
using data_type = std::remove_pointer_t<decltype(Data)>;
|
||||
|
||||
if constexpr(std::is_pointer_v<decltype(Data)>) {
|
||||
static_assert(Policy::template value<decltype(*Data)>, "Invalid return type for the given policy");
|
||||
} else {
|
||||
static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
|
||||
}
|
||||
|
||||
base_type::data(
|
||||
internal::meta_data_node{
|
||||
id,
|
||||
@@ -334,7 +346,7 @@ public:
|
||||
&internal::resolve<std::remove_cv_t<std::remove_reference_t<data_type>>>,
|
||||
&meta_arg<type_list<std::remove_cv_t<std::remove_reference_t<data_type>>>>,
|
||||
&meta_setter<Type, Data>,
|
||||
&meta_getter<Type, Data>});
|
||||
&meta_getter<Type, Data, Policy>});
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -345,12 +357,13 @@ public:
|
||||
* getter.
|
||||
* @tparam Setter The actual function to use as a setter.
|
||||
* @tparam Getter The actual function to use as a getter.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param name A custom unique identifier as a **string literal**.
|
||||
* @return A meta factory for the given type.
|
||||
*/
|
||||
template<auto Setter, auto Getter>
|
||||
template<auto Setter, auto Getter, typename Policy = as_is_t>
|
||||
meta_factory data(const char *name) noexcept {
|
||||
return data<Setter, Getter>(entt::hashed_string::value(name), name);
|
||||
return data<Setter, Getter, Policy>(entt::hashed_string::value(name), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,13 +382,15 @@ public:
|
||||
*
|
||||
* @tparam Setter The actual function to use as a setter.
|
||||
* @tparam Getter The actual function to use as a getter.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param id Unique identifier.
|
||||
* @param name An optional name for the meta data as a **string literal**.
|
||||
* @return A meta factory for the parent type.
|
||||
*/
|
||||
template<auto Setter, auto Getter>
|
||||
template<auto Setter, auto Getter, typename Policy = as_is_t>
|
||||
meta_factory data(const id_type id, const char *name = nullptr) noexcept {
|
||||
using descriptor = meta_function_helper_t<Type, decltype(Getter)>;
|
||||
static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
|
||||
|
||||
if constexpr(std::is_same_v<decltype(Setter), std::nullptr_t>) {
|
||||
base_type::data(
|
||||
@@ -388,7 +403,7 @@ public:
|
||||
&internal::resolve<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>>,
|
||||
&meta_arg<type_list<>>,
|
||||
&meta_setter<Type, Setter>,
|
||||
&meta_getter<Type, Getter>});
|
||||
&meta_getter<Type, Getter, Policy>});
|
||||
} else {
|
||||
using args_type = typename meta_function_helper_t<Type, decltype(Setter)>::args_type;
|
||||
|
||||
@@ -402,7 +417,7 @@ public:
|
||||
&internal::resolve<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>>,
|
||||
&meta_arg<type_list<type_list_element_t<static_cast<std::size_t>(args_type::size != 1u), args_type>>>,
|
||||
&meta_setter<Type, Setter>,
|
||||
&meta_getter<Type, Getter>});
|
||||
&meta_getter<Type, Getter, Policy>});
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -411,12 +426,13 @@ public:
|
||||
/**
|
||||
* @brief Assigns a meta function to a meta type.
|
||||
* @tparam Candidate The actual function to attach to the meta function.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param name A custom unique identifier as a **string literal**.
|
||||
* @return A meta factory for the given type.
|
||||
*/
|
||||
template<auto Candidate>
|
||||
template<auto Candidate, typename Policy = as_is_t>
|
||||
meta_factory func(const char *name) noexcept {
|
||||
return func<Candidate>(entt::hashed_string::value(name), name);
|
||||
return func<Candidate, Policy>(entt::hashed_string::value(name), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,13 +444,15 @@ public:
|
||||
* reflected object will appear as if they were part of the type itself.
|
||||
*
|
||||
* @tparam Candidate The actual function to attach to the meta type.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param id Unique identifier.
|
||||
* @param name An optional name for the function as a **string literal**.
|
||||
* @return A meta factory for the parent type.
|
||||
*/
|
||||
template<auto Candidate>
|
||||
template<auto Candidate, typename Policy = as_is_t>
|
||||
meta_factory func(const id_type id, const char *name = nullptr) noexcept {
|
||||
using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
|
||||
static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
|
||||
|
||||
base_type::func(
|
||||
internal::meta_func_node{
|
||||
@@ -442,9 +460,9 @@ public:
|
||||
name,
|
||||
(descriptor::is_const ? internal::meta_traits::is_const : internal::meta_traits::is_none) | (descriptor::is_static ? internal::meta_traits::is_static : internal::meta_traits::is_none),
|
||||
descriptor::args_type::size,
|
||||
&internal::resolve<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>>,
|
||||
&internal::resolve<std::conditional_t<std::is_same_v<Policy, as_void_t>, void, std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>>>,
|
||||
&meta_arg<typename descriptor::args_type>,
|
||||
&meta_invoke<Type, Candidate>});
|
||||
&meta_invoke<Type, Candidate, Policy>});
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
58
src/entt/meta/policy.hpp
Normal file
58
src/entt/meta/policy.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef ENTT_META_POLICY_HPP
|
||||
#define ENTT_META_POLICY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace entt {
|
||||
|
||||
/*! @brief Empty class type used to request the _as ref_ policy. */
|
||||
struct as_ref_t final {
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
template<typename Type>
|
||||
static constexpr bool value = std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>;
|
||||
/*! @endcond */
|
||||
};
|
||||
|
||||
/*! @brief Empty class type used to request the _as cref_ policy. */
|
||||
struct as_cref_t final {
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
template<typename Type>
|
||||
static constexpr bool value = std::is_reference_v<Type>;
|
||||
/*! @endcond */
|
||||
};
|
||||
|
||||
/*! @brief Empty class type used to request the _as-is_ policy. */
|
||||
struct as_is_t final {
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
template<typename>
|
||||
static constexpr bool value = true;
|
||||
/*! @endcond */
|
||||
};
|
||||
|
||||
/*! @brief Empty class type used to request the _as void_ policy. */
|
||||
struct as_void_t final {
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
template<typename>
|
||||
static constexpr bool value = true;
|
||||
/*! @endcond */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Provides the member constant `value` to true if a type also is a meta
|
||||
* policy, false otherwise.
|
||||
* @tparam Type Type to check.
|
||||
*/
|
||||
template<typename Type>
|
||||
struct is_meta_policy
|
||||
: std::bool_constant<std::is_same_v<Type, as_ref_t> || std::is_same_v<Type, as_cref_t> || std::is_same_v<Type, as_is_t> || std::is_same_v<Type, as_void_t>> {};
|
||||
|
||||
/**
|
||||
* @brief Helper variable template.
|
||||
* @tparam Type Type to check.
|
||||
*/
|
||||
template<typename Type>
|
||||
inline constexpr bool is_meta_policy_v = is_meta_policy<Type>::value;
|
||||
|
||||
} // namespace entt
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "../locator/locator.hpp"
|
||||
#include "meta.hpp"
|
||||
#include "node.hpp"
|
||||
#include "policy.hpp"
|
||||
|
||||
namespace entt {
|
||||
|
||||
@@ -76,7 +77,7 @@ template<typename Type, typename Ret, typename Class>
|
||||
struct meta_function_descriptor<Type, Ret Class::*>
|
||||
: meta_function_descriptor_traits<
|
||||
Ret &,
|
||||
std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Ret>, type_list<Class &, Ret>>,
|
||||
std::conditional_t<std::is_base_of_v<Class, Type>, type_list<>, type_list<Class &>>,
|
||||
!std::is_base_of_v<Class, Type>,
|
||||
false> {};
|
||||
|
||||
@@ -151,66 +152,73 @@ template<typename Type, typename Candidate>
|
||||
using meta_function_helper_t = typename meta_function_helper<Type, Candidate>::type;
|
||||
|
||||
/**
|
||||
* @brief Wraps a value and returns it.
|
||||
* @brief Wraps a value depending on the given policy.
|
||||
*
|
||||
* This function always returns a wrapped value in the requested context.<br/>
|
||||
* Therefore, if the passed value is itself a wrapped object with a different
|
||||
* context, it undergoes a rebinding to the requested context.
|
||||
*
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @tparam Type Type of value to wrap.
|
||||
* @param ctx The context from which to search for meta types.
|
||||
* @param value Value to wrap.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type>
|
||||
[[nodiscard]] meta_any meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) {
|
||||
if constexpr(std::is_lvalue_reference_v<Type> && !std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, meta_any>) {
|
||||
return meta_any{ctx, std::in_place_type<Type>, std::forward<Type>(value)};
|
||||
template<typename Policy = as_is_t, typename Type>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) {
|
||||
if constexpr(std::is_same_v<Policy, as_void_t>) {
|
||||
return meta_any{ctx, std::in_place_type<void>};
|
||||
} else if constexpr(std::is_same_v<Policy, as_ref_t>) {
|
||||
return meta_any{ctx, std::in_place_type<Type>, value};
|
||||
} else if constexpr(std::is_same_v<Policy, as_cref_t>) {
|
||||
static_assert(std::is_lvalue_reference_v<Type>, "Invalid type");
|
||||
return meta_any{ctx, std::in_place_type<const std::remove_reference_t<Type> &>, std::as_const(value)};
|
||||
} else {
|
||||
return meta_any{ctx, std::forward<Type>(value)};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wraps a value and returns it.
|
||||
* @brief Wraps a value depending on the given policy.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @tparam Type Type of value to wrap.
|
||||
* @param value Value to wrap.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type>
|
||||
[[nodiscard]] meta_any meta_dispatch(Type &&value) {
|
||||
return meta_dispatch<Type>(locator<meta_ctx>::value_or(), std::forward<Type>(value));
|
||||
template<typename Policy = as_is_t, typename Type>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(Type &&value) {
|
||||
return meta_dispatch<Policy, Type>(locator<meta_ctx>::value_or(), std::forward<Type>(value));
|
||||
}
|
||||
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
namespace internal {
|
||||
|
||||
template<typename Candidate, typename... Args>
|
||||
template<typename Policy, typename Candidate, typename... Args>
|
||||
[[nodiscard]] meta_any meta_invoke_with_args(const meta_ctx &ctx, Candidate &&candidate, Args &&...args) {
|
||||
if constexpr(std::is_void_v<decltype(std::invoke(std::forward<Candidate>(candidate), args...))>) {
|
||||
std::invoke(std::forward<Candidate>(candidate), args...);
|
||||
return meta_any{ctx, std::in_place_type<void>};
|
||||
} else {
|
||||
return meta_dispatch(ctx, std::invoke(std::forward<Candidate>(candidate), args...));
|
||||
return meta_dispatch<Policy>(ctx, std::invoke(std::forward<Candidate>(candidate), args...));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type, typename Candidate, std::size_t... Index>
|
||||
template<typename Type, typename Policy, typename Candidate, std::size_t... Index>
|
||||
[[nodiscard]] meta_any meta_invoke(meta_handle &instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args, std::index_sequence<Index...>) {
|
||||
using descriptor = meta_function_helper_t<Type, std::remove_reference_t<Candidate>>;
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
|
||||
if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, const Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
|
||||
if(const auto *const clazz = instance->try_cast<const Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
|
||||
return meta_invoke_with_args(instance->context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
return meta_invoke_with_args<Policy>(instance->context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
}
|
||||
} else if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
|
||||
if(auto *const clazz = instance->try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
|
||||
return meta_invoke_with_args(instance->context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
return meta_invoke_with_args<Policy>(instance->context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
}
|
||||
} else {
|
||||
if(((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
|
||||
return meta_invoke_with_args(instance->context(), std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
return meta_invoke_with_args<Policy>(instance->context(), std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
|
||||
}
|
||||
}
|
||||
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
@@ -301,22 +309,23 @@ template<typename Type, auto Data>
|
||||
* @brief Gets the value of a given variable.
|
||||
* @tparam Type Reflected type to which the variable is associated.
|
||||
* @tparam Data The actual variable to get.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param instance An opaque instance of the underlying type, if required.
|
||||
* @return A meta any containing the value of the underlying variable.
|
||||
*/
|
||||
template<typename Type, auto Data>
|
||||
[[nodiscard]] meta_any meta_getter(meta_handle instance) {
|
||||
template<typename Type, auto Data, typename Policy = as_is_t>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_getter(meta_handle instance) {
|
||||
if constexpr(std::is_member_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
|
||||
if constexpr(!std::is_array_v<std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>>>) {
|
||||
if constexpr(std::is_invocable_v<decltype(Data), Type &>) {
|
||||
if(auto *clazz = instance->try_cast<Type>(); clazz) {
|
||||
return internal::meta_invoke_with_args(instance->context(), Data, *clazz);
|
||||
return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *clazz));
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr(std::is_invocable_v<decltype(Data), const Type &>) {
|
||||
if(auto *fallback = instance->try_cast<const Type>(); fallback) {
|
||||
return internal::meta_invoke_with_args(instance->context(), Data, *fallback);
|
||||
return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *fallback));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,38 +335,40 @@ template<typename Type, auto Data>
|
||||
if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
|
||||
return meta_any{meta_ctx_arg, instance->context()};
|
||||
} else {
|
||||
return meta_dispatch(instance->context(), *Data);
|
||||
return meta_dispatch<Policy>(instance->context(), *Data);
|
||||
}
|
||||
} else {
|
||||
return meta_dispatch(instance->context(), Data);
|
||||
return meta_dispatch<Policy>(instance->context(), Data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tries to _invoke_ an object given a list of erased parameters.
|
||||
* @tparam Type Reflected type to which the object to _invoke_ is associated.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @tparam Candidate The type of the actual object to _invoke_.
|
||||
* @param instance An opaque instance of the underlying type, if required.
|
||||
* @param candidate The actual object to _invoke_.
|
||||
* @param args Parameters to use to _invoke_ the object.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, typename Candidate>
|
||||
[[nodiscard]] meta_any meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) {
|
||||
return internal::meta_invoke<Type>(instance, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
template<typename Type, typename Policy = as_is_t, typename Candidate>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) {
|
||||
return internal::meta_invoke<Type, Policy>(instance, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tries to invoke a function given a list of erased parameters.
|
||||
* @tparam Type Reflected type to which the function is associated.
|
||||
* @tparam Candidate The actual function to invoke.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param instance An opaque instance of the underlying type, if required.
|
||||
* @param args Parameters to use to invoke the function.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, auto Candidate>
|
||||
[[nodiscard]] meta_any meta_invoke(meta_handle instance, meta_any *const args) {
|
||||
return internal::meta_invoke<Type>(instance, Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
|
||||
template<typename Type, auto Candidate, typename Policy = as_is_t>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, meta_any *const args) {
|
||||
return internal::meta_invoke<Type, Policy>(instance, Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,35 +409,37 @@ template<typename Type, typename... Args>
|
||||
* It's up to the caller to bind the arguments to the right context(s).
|
||||
*
|
||||
* @tparam Type Reflected type to which the object to _invoke_ is associated.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @tparam Candidate The type of the actual object to _invoke_.
|
||||
* @param ctx The context from which to search for meta types.
|
||||
* @param candidate The actual object to _invoke_.
|
||||
* @param args Parameters to use to _invoke_ the object.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, typename Candidate>
|
||||
template<typename Type, typename Policy = as_is_t, typename Candidate>
|
||||
[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, Candidate &&candidate, meta_any *const args) {
|
||||
if constexpr(meta_function_helper_t<Type, Candidate>::is_static || std::is_class_v<std::remove_cv_t<std::remove_reference_t<Candidate>>>) {
|
||||
meta_handle placeholder{meta_ctx_arg, ctx};
|
||||
return internal::meta_invoke<Type>(placeholder, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
return internal::meta_invoke<Type, Policy>(placeholder, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
} else {
|
||||
meta_handle target{*args};
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
|
||||
return internal::meta_invoke<Type>(target, std::forward<Candidate>(candidate), args + 1u, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
return internal::meta_invoke<Type, Policy>(target, std::forward<Candidate>(candidate), args + 1u, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tries to construct an instance given a list of erased parameters.
|
||||
* @tparam Type Reflected type to which the object to _invoke_ is associated.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @tparam Candidate The type of the actual object to _invoke_.
|
||||
* @param candidate The actual object to _invoke_.
|
||||
* @param args Parameters to use to _invoke_ the object.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, typename Candidate>
|
||||
[[nodiscard]] meta_any meta_construct(Candidate &&candidate, meta_any *const args) {
|
||||
return meta_construct<Type>(locator<meta_ctx>::value_or(), std::forward<Candidate>(candidate), args);
|
||||
template<typename Type, typename Policy = as_is_t, typename Candidate>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(Candidate &&candidate, meta_any *const args) {
|
||||
return meta_construct<Type, Policy>(locator<meta_ctx>::value_or(), std::forward<Candidate>(candidate), args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,25 +451,27 @@ template<typename Type, typename Candidate>
|
||||
*
|
||||
* @tparam Type Reflected type to which the function is associated.
|
||||
* @tparam Candidate The actual function to invoke.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param ctx The context from which to search for meta types.
|
||||
* @param args Parameters to use to invoke the function.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, auto Candidate>
|
||||
[[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args) {
|
||||
return meta_construct<Type>(ctx, Candidate, args);
|
||||
template<typename Type, auto Candidate, typename Policy = as_is_t>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(const meta_ctx &ctx, meta_any *const args) {
|
||||
return meta_construct<Type, Policy>(ctx, Candidate, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tries to construct an instance given a list of erased parameters.
|
||||
* @tparam Type Reflected type to which the function is associated.
|
||||
* @tparam Candidate The actual function to invoke.
|
||||
* @tparam Policy Optional policy (no policy set by default).
|
||||
* @param args Parameters to use to invoke the function.
|
||||
* @return A meta any containing the returned value, if any.
|
||||
*/
|
||||
template<typename Type, auto Candidate>
|
||||
[[nodiscard]] meta_any meta_construct(meta_any *const args) {
|
||||
return meta_construct<Type, Candidate>(locator<meta_ctx>::value_or(), args);
|
||||
template<typename Type, auto Candidate, typename Policy = as_is_t>
|
||||
[[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(meta_any *const args) {
|
||||
return meta_construct<Type, Candidate, Policy>(locator<meta_ctx>::value_or(), args);
|
||||
}
|
||||
|
||||
} // namespace entt
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <entt/meta/context.hpp>
|
||||
#include <entt/meta/factory.hpp>
|
||||
#include <entt/meta/meta.hpp>
|
||||
#include <entt/meta/policy.hpp>
|
||||
#include <entt/meta/resolve.hpp>
|
||||
|
||||
struct base {
|
||||
@@ -59,7 +60,7 @@ struct MetaCtor: ::testing::Test {
|
||||
|
||||
entt::meta_factory<clazz>{}
|
||||
.type("clazz"_hs)
|
||||
.ctor<&entt::registry::emplace_or_replace<clazz, const int &, const char &>>()
|
||||
.ctor<&entt::registry::emplace_or_replace<clazz, const int &, const char &>, entt::as_ref_t>()
|
||||
.ctor<const base &, int &>()
|
||||
.ctor<const int &, char>()
|
||||
.ctor<entt::overload<clazz(int)>(clazz::factory)>()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <entt/meta/factory.hpp>
|
||||
#include <entt/meta/meta.hpp>
|
||||
#include <entt/meta/node.hpp>
|
||||
#include <entt/meta/policy.hpp>
|
||||
#include <entt/meta/range.hpp>
|
||||
#include <entt/meta/resolve.hpp>
|
||||
#include "../../common/config.h"
|
||||
@@ -66,17 +67,6 @@ struct array {
|
||||
int local[4]; // NOLINT
|
||||
};
|
||||
|
||||
// waiting for C++20 and lambdas inlined as template arguments
|
||||
namespace {
|
||||
|
||||
const int &clazz_i_as_const_reference(const clazz &elem) {
|
||||
return elem.i;
|
||||
}
|
||||
|
||||
void clazz_i_as_void(const clazz &) {}
|
||||
|
||||
} // namespace
|
||||
|
||||
struct MetaData: ::testing::Test {
|
||||
void SetUp() override {
|
||||
using namespace entt::literals;
|
||||
@@ -92,10 +82,10 @@ struct MetaData: ::testing::Test {
|
||||
|
||||
entt::meta_factory<clazz>{}
|
||||
.type("clazz"_hs)
|
||||
.data<&clazz::i>("i"_hs)
|
||||
.data<&clazz::i, entt::as_ref_t>("i"_hs)
|
||||
.custom<char>('c')
|
||||
.traits(test::meta_traits::one | test::meta_traits::two | test::meta_traits::three)
|
||||
.data<&clazz::i, &clazz_i_as_const_reference>("ci"_hs)
|
||||
.data<&clazz::i, entt::as_cref_t>("ci"_hs)
|
||||
.data<&clazz::j>("j")
|
||||
.traits(test::meta_traits::one)
|
||||
.data<&clazz::h>("h"_hs, "hhh")
|
||||
@@ -104,7 +94,7 @@ struct MetaData: ::testing::Test {
|
||||
.traits(test::meta_traits::three)
|
||||
.data<'c'>("l"_hs)
|
||||
.data<&clazz::instance>("base"_hs)
|
||||
.data<&clazz::i, clazz_i_as_void>("void"_hs)
|
||||
.data<&clazz::i, entt::as_void_t>("void"_hs)
|
||||
.conv<int>();
|
||||
|
||||
entt::meta_factory<setter_getter>{}
|
||||
@@ -544,7 +534,7 @@ TEST_F(MetaData, AsVoid) {
|
||||
|
||||
ASSERT_TRUE(data);
|
||||
ASSERT_EQ(data.arity(), 1u);
|
||||
ASSERT_EQ(data.type(), entt::resolve<void>());
|
||||
ASSERT_EQ(data.type(), entt::resolve<int>());
|
||||
ASSERT_EQ(data.arg(0u), entt::resolve<int>());
|
||||
ASSERT_TRUE(data.set(instance, 1));
|
||||
ASSERT_EQ(instance.i, 1);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <entt/meta/factory.hpp>
|
||||
#include <entt/meta/meta.hpp>
|
||||
#include <entt/meta/policy.hpp>
|
||||
#include <entt/meta/range.hpp>
|
||||
#include <entt/meta/resolve.hpp>
|
||||
#include "../../common/config.h"
|
||||
@@ -88,19 +89,6 @@ double double_member(const double &value) {
|
||||
return value * value;
|
||||
}
|
||||
|
||||
// waiting for C++20 and lambdas inlined as template arguments
|
||||
namespace {
|
||||
|
||||
void elem_v_as_void(const function &elem, int &iv) {
|
||||
static_cast<void>(elem.v(iv));
|
||||
}
|
||||
|
||||
const int &elem_a_as_const(function &elem) {
|
||||
return elem.a();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
struct MetaFunc: ::testing::Test {
|
||||
void SetUp() override {
|
||||
using namespace entt::literals;
|
||||
@@ -124,7 +112,7 @@ struct MetaFunc: ::testing::Test {
|
||||
|
||||
entt::meta_factory<function>{}
|
||||
.type("func"_hs)
|
||||
.func<&entt::registry::emplace_or_replace<function>>("emplace"_hs)
|
||||
.func<&entt::registry::emplace_or_replace<function>, entt::as_ref_t>("emplace"_hs)
|
||||
.traits(test::meta_traits::one | test::meta_traits::two | test::meta_traits::three)
|
||||
.func<entt::overload<int(const base &, int, int)>(&function::f)>("f3"_hs)
|
||||
.traits(test::meta_traits::three)
|
||||
@@ -137,9 +125,9 @@ struct MetaFunc: ::testing::Test {
|
||||
.custom<char>('c')
|
||||
.func<function::h>("h"_hs)
|
||||
.func<function::k>("k"_hs)
|
||||
.func<&elem_v_as_void>("v"_hs)
|
||||
.func<&function::a>("a"_hs)
|
||||
.func<&elem_a_as_const>("ca"_hs)
|
||||
.func<&function::v, entt::as_void_t>("v"_hs)
|
||||
.func<&function::a, entt::as_ref_t>("a"_hs)
|
||||
.func<&function::a, entt::as_cref_t>("ca"_hs)
|
||||
.conv<int>();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/type_traits.hpp>
|
||||
#include <entt/meta/meta.hpp>
|
||||
#include <entt/meta/policy.hpp>
|
||||
#include <entt/meta/resolve.hpp>
|
||||
#include <entt/meta/utility.hpp>
|
||||
#include "../../common/config.h"
|
||||
@@ -58,20 +59,22 @@ using MetaUtilityDeathTest = MetaUtility;
|
||||
TEST_F(MetaUtility, MetaDispatch) {
|
||||
int value = 2;
|
||||
|
||||
auto as_ref = entt::meta_dispatch(value);
|
||||
auto as_cref = entt::meta_dispatch(std::as_const(value));
|
||||
auto as_copy = entt::meta_dispatch(static_cast<int &&>(value));
|
||||
auto as_void = entt::meta_dispatch<entt::as_void_t>(value);
|
||||
auto as_ref = entt::meta_dispatch<entt::as_ref_t>(value);
|
||||
auto as_cref = entt::meta_dispatch<entt::as_cref_t>(value);
|
||||
auto as_is = entt::meta_dispatch(value);
|
||||
|
||||
ASSERT_EQ(as_void.type(), entt::resolve<void>());
|
||||
ASSERT_EQ(as_ref.type(), entt::resolve<int>());
|
||||
ASSERT_EQ(as_cref.type(), entt::resolve<int>());
|
||||
ASSERT_EQ(as_copy.type(), entt::resolve<int>());
|
||||
ASSERT_EQ(as_is.type(), entt::resolve<int>());
|
||||
|
||||
ASSERT_NE(as_copy.try_cast<int>(), nullptr);
|
||||
ASSERT_NE(as_is.try_cast<int>(), nullptr);
|
||||
ASSERT_NE(as_ref.try_cast<int>(), nullptr);
|
||||
ASSERT_EQ(as_cref.try_cast<int>(), nullptr);
|
||||
ASSERT_NE(as_cref.try_cast<const int>(), nullptr);
|
||||
|
||||
ASSERT_EQ(as_copy.cast<int>(), 2);
|
||||
ASSERT_EQ(as_is.cast<int>(), 2);
|
||||
ASSERT_EQ(as_ref.cast<int>(), 2);
|
||||
ASSERT_EQ(as_cref.cast<int>(), 2);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <entt/entity/storage.hpp>
|
||||
#include <entt/meta/factory.hpp>
|
||||
#include <entt/meta/meta.hpp>
|
||||
#include <entt/meta/policy.hpp>
|
||||
#include <entt/meta/resolve.hpp>
|
||||
|
||||
enum class my_entity : entt::id_type {};
|
||||
@@ -30,9 +31,9 @@ meta_mixin<Type>::meta_mixin(const allocator_type &allocator)
|
||||
|
||||
entt::meta_factory<element_type>{}
|
||||
// cross registry, same type
|
||||
.template func<entt::overload<entt::storage_for_t<element_type, entt::entity> &(const entt::id_type)>(&entt::basic_registry<entt::entity>::storage<element_type>)>("storage"_hs)
|
||||
.template func<entt::overload<entt::storage_for_t<element_type, entt::entity> &(const entt::id_type)>(&entt::basic_registry<entt::entity>::storage<element_type>), entt::as_ref_t>("storage"_hs)
|
||||
// cross registry, different types
|
||||
.template func<entt::overload<entt::storage_for_t<element_type, my_entity> &(const entt::id_type)>(&entt::basic_registry<my_entity>::storage<element_type>)>("storage"_hs);
|
||||
.template func<entt::overload<entt::storage_for_t<element_type, my_entity> &(const entt::id_type)>(&entt::basic_registry<my_entity>::storage<element_type>), entt::as_ref_t>("storage"_hs);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
|
||||
Reference in New Issue
Block a user