fusion::result_of::transform<Seq1,Seq2,F>
hello, here's what I'm trying to do: *.cpp //result_type() not valid typedef fusion::vector<A,B,C> result_type; //arg2s_type() is valid typedef fusion::vector<Arg2A,Arg2B,Arg2C> arg2s_type; //transforms // (fusion::vector<identity<A>,identity<B>,identity<C> >(),arg2s_type()) // into {A(arg1,Arg2A()),B(arg1,Arg2B()),C(arg1,Arg2C()))} result_type result( range<result_type,args2_type>::create( arg1 //arbitrary type Arg1 ) ); here's my attempt. problems/questions are shown in comments. *.hpp: template<template<typename> class metafun = mpl::identity> struct apply_wrapper{ template<typename T> struct apply{ typedef metafun<T> type; }; }; template<typename Seq,template<typename> class metafun = mpl::identity> struct apply_wrapper_to_seq{ typedef typename mpl::transform< Seq, // e.g. fusion::vector<A,B,C> apply_wrapper<metafun>
::type type; //e.g. fusion::vector<identity<A>,identity<B>,identity<C> > };
template<typename Arg1> struct fun{ fun(const Arg1& args):args_(args_){} //copy, assign... // probably not what result_of::transform expects, based on compile // errors (below) template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; }; template<typename Metafun,typename Arg2> typename Metafun::type //e.g Metafun = identity<A> operator()(const Metafun& meta,const Arg2& arg2)const{ typedef typename Metafun::type result_type; //e.g. A return result_type(args,arg2); } const Arg1& args_; }; template<typename Result,typename Arg2s> struct range{ //e.g. fusion<identity<A>,identity<B>,identity<C> > typedef typename apply_wrapper_to_seq<Result>::type wrappers_type; //e.g. fusion::vector<Arg2A,Arg2B,Arg2C> typedef Arg2s arg2s_type; template<typename Arg1> struct result{ typedef typename fusion::result_of::transform< wrappers_type, arg2s_type, fun<Arg1>
::type type; };
template<typename Arg1> static typename result<Arg1>::type create(const Arg1& args){ typedef fun<Arg1> f_type; wrappers_type wrappers; arg2s_type arg2s; f_type f(args); BOOST_MPL_ASSERT( ( mpl::equal< Result, typename result<Arg1>::type > ) );//result_of::fun causes compile error /usr/local/boost_1_35_0/boost/utility/result_of.hpp|34|instantiated from ‘boost::detail::result_of_impl< factory::fun<Arg1>, factory::fun<Arg1> > ()(boost::mpl::identity<A>, Arg2A), false>’| ... //usr/local/boost_1_35_0/boost/utility/result_of.hpp|68|error: wrong number of template arguments (1, should be 2)| //factory/range.hpp|32|error: provided for ‘template<class Arg1> template<class Metafun, class Arg2> struct factory::fun<Arg1>::result’| //usr/local/boost_1_35_0/boost/fusion/view/transform_view/detail/value_of_impl.hpp|55|error: no type named ‘type’ in ‘struct //boost::mpl::apply<boost::fusion::detail::apply_transform_result<factory::fun<Arg1>, boost::mpl::identity<A>, Arg2A, mpl_::na, mpl_::na, mpl_::na>’| return fusion::transform( wrappers, arg2s, f ); } }; any help would appreciated. thanks!
AMDG e r wrote:
// probably not what result_of::transform expects, based on compile // errors (below) template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; };
Fusion uses Boost.ResultOf. http://www.boost.org/doc/libs/1_36_0/libs/utility/utility.htm#result_of In Christ, Steven Watanabe
Steven Watanabe wrote:
AMDG
e r wrote:
// probably not what result_of::transform expects, based on compile // errors (below) template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; };
Fusion uses Boost.ResultOf. http://www.boost.org/doc/libs/1_36_0/libs/utility/utility.htm#result_of
In Christ, Steven Watanabe
Thanks. I read the link above before posting as well as the proposal: //example from proposal. struct square_ { template<typename T> struct result { typedef T type; } template<typename T> T operator()(T& x) const { return x*x; } }; but I'm not qualified enough to deduce the right answer in my case. i thought id would be like this: template<typename Arg1> struct fun{ template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; }; template<typename Metafun,typename Arg2> typename Metafun::type operator()(const Metafun& meta,const Arg2& arg2)const{ typedef typename Metafun::type result_type; return result_type(args,arg2); } }; but apparently it's not correct. I guess I can't fully make sense of F::result<F(T1, T2, ..., TN)>::type. any hint here would be really helpful. thanks!
e r wrote:
Steven Watanabe wrote:
AMDG
e r wrote:
// probably not what result_of::transform expects, based on compile // errors (below) template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; };
Fusion uses Boost.ResultOf. http://www.boost.org/doc/libs/1_36_0/libs/utility/utility.htm#result_of
In Christ, Steven Watanabe
Thanks. I read the link above before posting as well as the proposal:
//example from proposal. struct square_ { template<typename T> struct result { typedef T type; }
template<typename T> T operator()(T& x) const { return x*x; } };
but I'm not qualified enough to deduce the right answer in my case. i thought id would be like this:
template<typename Arg1> struct fun{ template<typename Metafun,typename Arg2> struct result{ typedef typename Metafun::type type; };
template<typename Metafun,typename Arg2> typename Metafun::type operator()(const Metafun& meta,const Arg2& arg2)const{ typedef typename Metafun::type result_type; return result_type(args,arg2); } };
but apparently it's not correct. I guess I can't fully make sense of F::result<F(T1, T2, ..., TN)>::type. any hint here would be really helpful.
thanks!
I may have made a little bit of progress here... struct fun{ template<typename Signature> struct result; template<typename A> struct result<fun(const A&)>{ typedef A type; }; template<typename A> A operator()(const A& a)const{ return A(); }; }; typedef boost::result_of<fun(const my&)>::type result_type; BOOST_MPL_ASSERT( ( mpl::is_same< result_type, my > ) );
AMDG e r wrote:
I may have made a little bit of progress here...
template<typename A> struct result<fun(const A&)>{ typedef A type; };
Yeah. That's the idea. I generally use function_traits rather than partial specialization. In your original example (untested): #include <boost/type_traits/function_traits.hpp> #include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_refence.hpp> struct fun { template<class Sig> struct result { typedef typename boost::function_traits<Sig>::arg1_type arg1_type; typedef typename boost::function_traits<Sig>::arg2_type arg2_type; typedef typename boost::remove_cv<typename boost::remove_reference<arg1_type>::type>::type Metafun; typedef typename Metafun::type type; }; // ... } In Christ, Steven Watanabe
Steven Watanabe wrote:
AMDG
e r wrote:
I may have made a little bit of progress here...
template<typename A> struct result<fun(const A&)>{ typedef A type; };
Yeah. That's the idea. I generally use function_traits rather than partial specialization. In your original example (untested):
#include <boost/type_traits/function_traits.hpp> #include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_refence.hpp>
struct fun { template<class Sig> struct result { typedef typename boost::function_traits<Sig>::arg1_type arg1_type; typedef typename boost::function_traits<Sig>::arg2_type arg2_type; typedef typename boost::remove_cv<typename boost::remove_reference<arg1_type>::type>::type Metafun; typedef typename Metafun::type type; }; // ... }
In Christ, Steven Watanabe
Much appreciated, thanks! made changes as suggested and works. but i can't get this simple algorithm to work (errors shown in the code below). please help. algorithm: map fusion::vector<A,B,C,...> to fusion::vector<identity<A>,identity<B>,identity<C>,...> and call {identity<X>::type(arg):X=A,B,C,...} via transform. use the result to copy construct fusion::vector<A,B,C,...>. *.cpp typedef boost::fusion::vector2<boost::mpl::int_<0>,boost::mpl::int_<1> > vec1_type; typedef boost::range<vec1_type> range_type; range_type::result::type result( range_type::create() ); vec1_type vec1 = result; // error: no matching function for call to ‘boost::fusion::vector_data2<boost::fusion::vector2<mpl_::int_<0>, mpl_::int_<1> >, mpl_::int_<0>, mpl_::int_<1> >::vector_data2(const boost::mpl::identity<mpl_::int_<0> >, const boost::mpl::identity<mpl_::int_<1> >)’| *.hpp template<template<typename> class metafun = mpl::identity> struct apply_wrapper{ template<typename T> struct apply{ typedef metafun<T> type; }; }; template<typename Seq,template<typename> class metafun = mpl::identity> struct apply_wrapper_to_seq{ typedef typename mpl::transform<Seq,apply_wrapper<metafun> >::type type; }; struct range_fun{ range_fun(){} template<class Signature> struct result { typedef boost::function_traits<Signature> fun_traits; typedef typename fun_traits::arg1_type arg1_type; typedef typename boost::remove_cv< typename boost::remove_reference<arg1_type> >::type metafun_type; typedef typename metafun_type::type type; }; template<typename Metafun> typename Metafun::type operator()(const Metafun& meta)const{ typedef typename Metafun::type result_type; return result_type(); //for now arg2 ommitted for simplicity } }; template<typename Result> struct range{ typedef typename apply_wrapper_to_seq<Result>::type wrappers_type; struct result{ typedef typename fusion::result_of::transform< const wrappers_type,range_fun>::type type; }; //ommitting const causes compile error static typename result::type create(){ typedef range_fun f_type; BOOST_MPL_ASSERT((mpl::equal<Result,typename result::type>));//mpl_::failed (see below) return fusion::transform(wrappers_type(),f_type()); } }; no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::equal<boost::fusion::vector2<mpl_::int_<0>, mpl_::int_<1> >, boost::fusion::transform_view<const boost::fusion::vector<boost::mpl::identity<mpl_::int_<0> >, boost::mpl::identity<mpl_::int_<1> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::range_fun, boost::fusion::void_>, boost::is_same<mpl_::arg<-0x00000000000000001>, mpl_::arg<-0x00000000000000001> > >::************)’|
AMDG e r wrote:
typedef typename boost::remove_cv< typename boost::remove_reference<arg1_type> >::type metafun_type;
This should be typename boost::remove_reference<arg1_type>::type.
typedef typename metafun_type::type type; };
In Christ, Steven Watanabe
Steven Watanabe wrote:
AMDG
e r wrote:
typedef typename boost::remove_cv< typename boost::remove_reference<arg1_type> >::type metafun_type;
This should be typename boost::remove_reference<arg1_type>::type.
typedef typename metafun_type::type type; };
In Christ, Steven Watanabe
Oh! I should have spotted that. Thanks for following up throughout!
participants (2)
-
e r
-
Steven Watanabe