File interface_traits.hpp¶
File List > backends > cxx > include > zmbt > core > interface_traits.hpp
Go to the documentation of this file
#ifndef ZMBT_CORE_INTERFACE_TRAITS_HPP_
#define ZMBT_CORE_INTERFACE_TRAITS_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "aliases.hpp"
#include "generic_traits.hpp"
namespace zmbt {
// PREDICATES
template<class Interface, class DecayedInterface = decay_t<Interface>>
using ifc_is_pmf_handle = is_member_function_pointer<DecayedInterface>;
template<class Interface, class DecayedInterface = decay_t<Interface>>
using ifc_is_pmd_handle = is_member_object_pointer<DecayedInterface>;
template<class Interface, class DecayedInterface = decay_t<Interface>>
using ifc_is_member_handle = is_member_pointer<DecayedInterface>;
template<class Interface, class DecayedInterface = decay_t<Interface>>
using ifc_is_fn_ref = mp_all<
is_lvalue_reference<Interface>,
is_function<remove_pointer_t<DecayedInterface>>
>;
template<class Interface, class DecayedInterface = decay_t<Interface>>
using ifc_is_fn_ptr = mp_all<
is_pointer<Interface>,
is_function<remove_pointer_t<DecayedInterface>>
>;
template<class Interface>
using ifc_is_fn_handle = mp_any<
ifc_is_fn_ref<Interface>, ifc_is_fn_ptr<Interface>
>;
namespace detail {
template<class Interface, class = void>
struct support_calltraits_function : mp_false {};
template<class Interface>
struct support_calltraits_function<Interface, void_t<ct::function_type_t<Interface>>> : mp_true {};
}
template<class Interface, class InterfacePointer = remove_reference_t<Interface>, class Functor = remove_pointer_t<InterfacePointer>>
using ifc_is_functor_ptr = mp_all<
is_pointer<InterfacePointer>, is_class<Functor>,
detail::support_calltraits_function<Functor>
>;
template<class Interface, class Functor = remove_reference_t<Interface>>
using ifc_is_functor_ref = mp_all<
is_reference<Interface>, is_class<Functor>,
detail::support_calltraits_function<Functor>
>;
template <class Interface>
using ifc_is_functor_handle = mp_any<
ifc_is_functor_ptr<Interface>,
ifc_is_functor_ref<Interface>
>;
template<class Interface>
using is_ifc_handle = mp_any<
ifc_is_pmf_handle<Interface>,
ifc_is_pmd_handle<Interface>,
ifc_is_fn_handle<Interface>,
ifc_is_functor_handle<Interface>
>;
template <class Interface, class Result = decay_t<Interface>>
auto get_ifc_pointer (Interface x) -> first_if_t<Result,
ifc_is_member_handle<Interface>
>
{
return x;
}
template <class Interface, class Result = decay_t<Interface>>
auto get_ifc_pointer (Interface x) -> first_if_t<Result,
ifc_is_fn_handle<Interface>
>
{
return x;
}
template <class Interface, class Result = add_pointer_t<remove_reference_t<Interface>>>
auto get_ifc_pointer (Interface* x) -> first_if_t<Result,
ifc_is_functor_ptr<Interface*>
>
{
return x;
}
template <class Interface, class Result = add_pointer_t<remove_reference_t<Interface>>>
auto get_ifc_pointer (Interface& x) -> first_if_t<Result,
ifc_is_functor_ref<Interface&>
>
{
return &x;
}
template <class Interface, class Result = decay_t<Interface> const>
auto get_ifc_handle (Interface const x) -> first_if_t<Result,
ifc_is_member_handle<Interface>
>
{
return x;
}
template <class Interface, class Result = decay_t<Interface> const>
auto get_ifc_handle (Interface const x) -> first_if_t<Result,
ifc_is_fn_handle<Interface>
>
{
return x;
}
template <class Interface, class Result = add_lvalue_reference_t<Interface> const>
auto get_ifc_handle (Interface * x) -> first_if_t<Result,
ifc_is_functor_ptr<Interface*>
>
{
return &x;
}
template <class Interface, class Result = add_lvalue_reference_t<Interface> const>
auto get_ifc_handle (Interface & x) -> first_if_t<Result,
ifc_is_functor_ref<Interface&>
>
{
return x;
}
namespace detail {
template <class Interface>
using ifc_pointer_valid_t = decltype(get_ifc_pointer(std::declval<Interface>()));
}
template <class Interface>
struct ifc_pointer {
using type = mp_eval_or<nullptr_t, detail::ifc_pointer_valid_t, Interface>;
};
template <class Interface>
using ifc_pointer_t = typename ifc_pointer<Interface>::type;
namespace detail {
template <class Interface>
using ifc_handle_valid_t = decltype(get_ifc_handle(std::declval<Interface>()));
}
template <class Interface>
struct ifc_handle {
using type = mp_eval_or<nullptr_t, detail::ifc_handle_valid_t, Interface>;
};
template <class Interface>
using ifc_handle_t = typename ifc_handle<Interface>::type;
// PART TRAITS
namespace detail {
template <class T>
struct qualified_class_of {
using type = ct::qualified_class_of_t<T>;
};
}
template <class Interface, class = void>
struct ifc_host {
using type = typename mp_if<ifc_is_member_handle<Interface>, ct::qualified_class_of<Interface>, mp_identity<nullptr_t>>::type;
};
template <class Interface>
using ifc_host_t = typename ifc_host<Interface>::type;
template <class Interface>
constexpr add_pointer_t<remove_reference_t<ifc_host_t<Interface>>> ifc_host_nullptr {};
namespace detail {
template <class Interface, class = void>
struct ifc_args_impl {
using type = ct::args_t<remove_pointer_t<Interface>>;
};
template <class Interface>
struct ifc_args_impl <Interface, first_if_t<void_t<ct::args_t<Interface>>, ifc_is_member_handle<Interface>>> {
using type = mp_rest<ct::args_t<Interface>>;
};
template <class Interface>
struct ifc_args_impl <Interface, first_if_none_t<void_t<ct::args_t<Interface>>, ifc_is_member_handle<Interface> >> {
using type = ct::args_t<Interface>;
};
} // namespace detail
template <class Interface>
struct ifc_args
{
using type = typename mp_eval_or<mp_identity<void>, detail::ifc_args_impl, ifc_handle_t<Interface>>::type;
};
template <class Interface>
using ifc_args_t = typename ifc_args<Interface>::type;
template <class Interface>
struct ifc_return : ct::return_type<Interface> {
using type = typename mp_eval_or<mp_identity<void>, ct::return_type, ifc_handle_t<Interface>>::type;
};
template <class Interface>
using ifc_return_t = typename ifc_return<Interface>::type;
} // namespace zmbt
#endif // ZMBT_CORE_INTERFACE_TRAITS_HPP_