File invocation.hpp¶
File List > backends > cxx > include > zmbt > reflect > invocation.hpp
Go to the documentation of this file
#ifndef ZMBT_REFLECT_INTERFACE_HPP_
#define ZMBT_REFLECT_INTERFACE_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "zmbt/core.hpp"
#define DEFAULT_INVOCATION_TYPEDEFS \
using host_t = ifc_host_t<type>; \
using return_t = ifc_return_t<type>; \
using args_t = ifc_args_t<type>;
namespace zmbt {
namespace reflect {
template <class T, class E = void>
struct invocation;
template <class T, class E = void>
struct custom_invocation;
namespace detail {
template<class T>
using custom_invocation_t = typename custom_invocation<T>::type;
template<class T>
using has_custom_invocation = mp_valid<custom_invocation_t, T>;
template <class T>
using enable_default_invocation = first_if_t<void,
is_ifc_handle<T>,
mp_not<has_custom_invocation<ifc_pointer_t<T>>>
>;
template <class T>
using enable_custom_invocation = first_if_t<void, has_custom_invocation<ifc_pointer_t<T>>>;
} // namespace detail
template <class S, class E = void>
struct default_invocation;
template <class S>
struct default_invocation<S, first_if_t<void, ifc_is_member_handle<S>>>
{
using type = S;
DEFAULT_INVOCATION_TYPEDEFS
template <class H>
static return_t apply(H&& object, type ifc, args_t args)
{
return boost::mp11::tuple_apply(std::mem_fn(ifc), std::tuple_cat(std::forward_as_tuple(object), args));
}
};
template <class S>
struct default_invocation<S, first_if_any_t<void, ifc_is_fn_handle<S>, ifc_is_functor_ref<S>>>
{
using type = S;
DEFAULT_INVOCATION_TYPEDEFS
static return_t apply(host_t, type ifc, args_t args)
{
static_assert(std::is_same<host_t, nullptr_t>::value, "");
return boost::mp11::tuple_apply(ifc, args);
}
};
template <class S>
struct default_invocation<S, first_if_t<void, ifc_is_functor_ptr<S>>>
{
using type = S;
DEFAULT_INVOCATION_TYPEDEFS
static return_t apply(host_t, type ifc, args_t args)
{
static_assert(std::is_same<host_t, nullptr_t>::value, "");
return boost::mp11::tuple_apply(*ifc, args);
}
};
template <class S>
struct invocation<S, detail::enable_default_invocation<S>> : default_invocation<ifc_pointer_t<S>> {};
template <class S>
struct invocation<S, detail::enable_custom_invocation<S>> : custom_invocation<ifc_pointer_t<S>> {};
template<class T, class E = void>
struct has_invocation_for : std::false_type { };
template<class T>
struct has_invocation_for<T, void_t<typename invocation<T>::type>> : std::true_type { };
template <class I>
using interface_t = typename reflect::invocation<I>::type;
template <class T>
using invocation_args_t = typename invocation<T>::args_t;
template <class T>
using invocation_args_unqf_t = tuple_unqf_t<invocation_args_t<T>>;
template <class T>
using invocation_has_void_args = std::integral_constant<bool, 0 == boost::mp11::mp_size<invocation_args_t<T>>::value >;
template <class T>
using invocation_ret_t = typename invocation<T>::return_t;
template <class T>
using invocation_unqf_ret_t = remove_cvref_t<invocation_ret_t<T>>;
template <class T>
using invocation_has_void_ret = std::is_void<invocation_ret_t<T>>;
template <class T>
using invocation_host_t = typename invocation<T>::host_t;
template <class T>
using invocation_unqf_host_t = remove_cvref_t<invocation_host_t<T>>;
} // namespace reflect
} // namespace zmbt
#undef DEFAULT_INVOCATION_TYPEDEFS
#endif // ZMBT_REFLECT_INTERFACE_PLUGIN_DEFAULT_HPP_