Create an invocable from other invocables(quoted metafunctions) by composition.
#ifndef __utl_meta_invoke_h__
#define __utl_meta_invoke_h__
namespace meta{
template <typename _Tp>
struct identity {
#if defined (UTL_WORKAROUND_CWG_1558)
template <typename... Ts>
#else
template <typename...>
#endif
};
template <typename _Tp>
template <typename Fn, typename... Args>
template <typename Fn, typename... Args>
template <template <typename...> class F>
struct wrap {
template <typename... Args>
using apply = F<Args...>;
};
template <typename T, template <T...> class F>
struct wrap_i {
template <typename... Ts>
using apply = F<Ts::type::value...>;
};
namespace detail {
template<template<typename...> class F, typename... T>
struct is_applicable_ {
template<template<typename...> class G, typename = G<T...>>
template<template<typename...> class>
using type = decltype(check<F>(0));
};
template<typename F, typename... T>
struct is_applicable_q_ {
template<
typename G,
typename Ret =
invoke_t<G, T...>>
template<typename...>
nil_,
decltype(check<F>(0))
>;
};
template<typename T, template <T...> class F, T... Is>
struct is_applicable_i_ {
template<typename TT, template<TT...> class G, typename = G<Is...>>
template<typename TT, template<TT...> class G>
using type = decltype(check<T, F>(0));
};
}
template<template<typename...> class F, typename... T>
detail::is_applicable_<F, T...>
>;
template<typename Q, typename... T>
detail::is_applicable_q_ <Q, T...>
>;
template <typename T, template<T...> class F, T... Is>
detail::is_applicable_i_<T, F, Is...>
>;
namespace detail {
template<template<typename...> class F, typename... Ts>
struct defer_ {
};
template<typename T, template<T...> class F, T... Is>
struct defer_i_ {
};
}
template<template<class...> class F, class... Ts>
detail::is_applicable_<F, Ts...>,
detail::defer_<F, Ts...>,
nil_
>;
template <typename T, template<T...> class F, T... Is>
detail::is_applicable_i_<T, F, Is...>,
detail::defer_i_<T, F, Is...>,
nil_
>;
template <template <typename...> class F>
struct quote {
template <typename... Args>
>;
};
template <typename T, template <T...> class F>
struct quote_i {
template <typename... Ts>
>;
};
namespace detail {
template <template <typename...> class... Fns> struct compose_f_ {};
template <template <typename...> class Fn0,
template <typename...> class... Fns>
struct compose_f_<Fn0, Fns...> {
template <typename... Args>
quote<Fn0>,
invoke<compose_f_<Fns...>, Args...>
>;
};
template <template <typename...> class Fn0>
struct compose_f_<Fn0> {
template <typename ...Args>
using apply = invoke<quote<Fn0>, Args...>;
};
template<typename ...Fns> struct compose_ {};
template<typename Fn0, typename ...Fns>
struct compose_<Fn0, Fns...> {
template <typename ...Args>
Fn0,
invoke<compose_<Fns...>, Args...>
>;
};
template<typename Fn0>
struct compose_<Fn0> {
template <typename... Args>
};
}
template <typename... Fns>
using compose = detail::compose_<Fns...>;
template <template <typename...> class... Fns>
using compose_f = detail::compose_f_<Fns...>;
template<typename Fn, typename... Ts>
struct bind_front {
template<typename... Us>
};
template<typename Fn, typename... Ts>
struct bind_back {
template<typename... Us>
};
template <typename T1>
struct same_as {
template <typename T2>
struct apply : same_<T1, T2> { };
};
template <typename T1>
struct not_same_as {
template <typename T2>
};
}}
#endif