在没有预处理器的情况下从 hana 元组创建函数签名
Create a function signature from a hana tuple without the preprocessor
有没有不用预处理器的方法?
#include <boost/hana.hpp>
#include <boost/preprocessor.hpp>
namespace ba = boost::hana;
template <typename Arguments, unsigned ArgCount>
struct FunctionSigCreatorImpl {};
template <typename Arguments>
struct FunctionSigCreator : FunctionSigCreatorImpl<Arguments, decltype(ba::length(Arguments{}))::value>
{
};
#define DEF_ARG(z, n, data) \
typename decltype(+ba::at(Arguments{}, ba::int_c<n>))::type
#define DEF_FUN_CREATOR(z, argCount, data) \
template <typename Arguments> \
struct FunctionSigCreatorImpl<Arguments, argCount> \
{ \
using Type = void(BOOST_PP_ENUM(argCount, DEF_ARG,)); \
};
BOOST_PP_REPEAT(19, DEF_FUN_CREATOR,)
int main(int argc, char **argv)
{
using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::Type, void(int, long, char)>::value);
return 0;
}
#include <boost/hana.hpp>
#include <boost/hana/tuple.hpp>
namespace ba = boost::hana;
template<typename ... Types>
ba::type<void(typename Types::type...)> FunctionSigCreatorImpl(ba::tuple<Types...>){ return{}; }
template<typename Tuple>
using FunctionSigCreator = decltype(FunctionSigCreatorImpl(std::declval<Tuple>()));
int main()
{
using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
//using MyTuple = decltype(ba::tuple_t<int,long,char>);
static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::type, void(int, long, char)>::value);
return 0;
}
Boost.CallableTraits 可以用 apply_return
来做到这一点。
#include <boost/callable_traits.hpp>
#include <boost/hana.hpp>
#include <tuple>
#include <type_traits>
namespace hana = boost::hana;
namespace ct = boost::callable_traits;
template <typename Tuple>
using to_function_sig = ct::apply_return_t<
typename decltype(hana::unpack(Tuple{}, hana::template_<std::tuple>))::type,
void
>;
int main()
{
using MyTuple = hana::tuple<hana::type<int>, hana::type<long>, hana::type<char>>;
static_assert(std::is_same<to_function_sig<MyTuple>, void(int, long, char)>::value, "");
}
有没有不用预处理器的方法?
#include <boost/hana.hpp>
#include <boost/preprocessor.hpp>
namespace ba = boost::hana;
template <typename Arguments, unsigned ArgCount>
struct FunctionSigCreatorImpl {};
template <typename Arguments>
struct FunctionSigCreator : FunctionSigCreatorImpl<Arguments, decltype(ba::length(Arguments{}))::value>
{
};
#define DEF_ARG(z, n, data) \
typename decltype(+ba::at(Arguments{}, ba::int_c<n>))::type
#define DEF_FUN_CREATOR(z, argCount, data) \
template <typename Arguments> \
struct FunctionSigCreatorImpl<Arguments, argCount> \
{ \
using Type = void(BOOST_PP_ENUM(argCount, DEF_ARG,)); \
};
BOOST_PP_REPEAT(19, DEF_FUN_CREATOR,)
int main(int argc, char **argv)
{
using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::Type, void(int, long, char)>::value);
return 0;
}
#include <boost/hana.hpp>
#include <boost/hana/tuple.hpp>
namespace ba = boost::hana;
template<typename ... Types>
ba::type<void(typename Types::type...)> FunctionSigCreatorImpl(ba::tuple<Types...>){ return{}; }
template<typename Tuple>
using FunctionSigCreator = decltype(FunctionSigCreatorImpl(std::declval<Tuple>()));
int main()
{
using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
//using MyTuple = decltype(ba::tuple_t<int,long,char>);
static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::type, void(int, long, char)>::value);
return 0;
}
Boost.CallableTraits 可以用 apply_return
来做到这一点。
#include <boost/callable_traits.hpp>
#include <boost/hana.hpp>
#include <tuple>
#include <type_traits>
namespace hana = boost::hana;
namespace ct = boost::callable_traits;
template <typename Tuple>
using to_function_sig = ct::apply_return_t<
typename decltype(hana::unpack(Tuple{}, hana::template_<std::tuple>))::type,
void
>;
int main()
{
using MyTuple = hana::tuple<hana::type<int>, hana::type<long>, hana::type<char>>;
static_assert(std::is_same<to_function_sig<MyTuple>, void(int, long, char)>::value, "");
}