Ticket #4569: unfused.patch
File unfused.patch, 10.0 KB (added by , 12 years ago) |
---|
-
unfused.hpp
31 31 32 32 namespace boost { namespace fusion 33 33 { 34 template <class Function, bool AllowNullary = true>35 class unfuse d;34 template <class Derived, template<typename> class Result, bool AllowNullary = true> 35 class unfuse_interface; 36 36 37 37 //----- ---- --- -- - - - - 38 38 39 template <class Function>40 class unfuse d<Function,true>41 : public unfuse d<Function,false>39 template <class Derived, template<typename> class Result> 40 class unfuse_interface<Derived,Result,true> 41 : public unfuse_interface<Derived,Result,false> 42 42 { 43 typedef typename detail::qf_c<Function>::type function_c;44 typedef typename detail::qf<Function>::type function;45 typedef typename detail::call_param<Function>::type func_const_fwd_t;46 43 public: 44 using unfuse_interface<Derived,Result,false>::operator(); 47 45 48 using unfused<Function,false>::operator(); 46 template<typename Sig> 47 struct result 48 : unfuse_interface<Derived,Result,false>::result<Sig>{}; 49 49 50 inline explicit unfused(func_const_fwd_t f = function())51 : unfused<Function,false>(f)52 { }50 template<typename Self> 51 struct result<Self()> 52 : Result<Derived (fusion::vector0<> &)>{}; 53 53 54 typedef typename boost::result_of< 55 function_c(fusion::vector0<> &) >::type call_const_0_result; 54 template<typename Self> 55 struct result<Self const ()> 56 : Result<Derived const (fusion::vector0<> &)>{}; 56 57 57 inline call_const_0_resultoperator()() const58 inline typename result<Derived const ()>::type operator()() const 58 59 { 59 60 fusion::vector0<> arg; 60 return this->fnc_transformed(arg);61 return static_cast<Derived const *>(this)->call(arg); 61 62 } 62 63 63 typedef typename boost::result_of< 64 function(fusion::vector0<> &) >::type call_0_result; 65 66 inline call_0_result operator()() 64 inline typename result<Derived ()>::type operator()() 67 65 { 68 66 fusion::vector0<> arg; 69 return this->fnc_transformed(arg);67 return static_cast<Derived *>(this)->call(arg); 70 68 } 71 69 }; 72 70 73 template <class Function> class unfused<Function,false> 71 template <class Derived, template<typename> class Result> 72 class unfuse_interface<Derived, Result,false> 74 73 { 75 protected:76 Function fnc_transformed;77 typedef typename detail::qf_c<Function>::type function_c;78 typedef typename detail::qf<Function>::type function;79 typedef typename detail::call_param<Function>::type func_const_fwd_t;80 74 public: 81 82 inline explicit unfused(func_const_fwd_t f = function())83 : fnc_transformed(f)84 { }85 86 75 template <typename Sig> 87 76 struct result; 88 77 … … 91 80 #define BOOST_PP_ITERATION_LIMITS \ 92 81 (1,BOOST_FUSION_UNFUSED_MAX_ARITY) 93 82 #include BOOST_PP_ITERATE() 83 84 //perfect forwarding for up to 2 arguments: 85 template <typename T0,typename T1> 86 inline typename result< Derived const (T0 const &,T1 &) >::type 87 operator()(T0 const &a0,T1 &a1) const{ 88 fusion::vector2<T0 const &,T1 &> arg(a0,a1); 89 return static_cast<Derived const *>(this)->call(arg); 90 } 91 template <typename T0,typename T1> 92 inline typename result< Derived const (T0 const &,T1 &) >::type 93 operator()(T0 const &a0,T1 &a1){ 94 fusion::vector2<T0 const &,T1 &> arg(a0,a1); 95 return static_cast<Derived *>(this)->call(arg); 96 } 97 template <typename T0,typename T1> 98 inline typename result< Derived const (T0 &,T1 const &) >::type 99 operator()(T0 &a0,T1 const &a1) const{ 100 fusion::vector2<T0 &,T1 const &> arg(a0,a1); 101 return static_cast<Derived const *>(this)->call(arg); 102 } 103 template <typename T0,typename T1> 104 inline typename result< Derived const (T0 &,T1 const &) >::type 105 operator()(T0 &a0,T1 const &a1){ 106 fusion::vector2<T0 &,T1 const &> arg(a0,a1); 107 return static_cast<Derived *>(this)->call(arg); 108 } 94 109 }; 110 111 namespace detail{ 112 113 template<typename Function> 114 struct fused_result{ 115 typedef typename detail::qf_c<Function>::type function_c; 116 typedef typename detail::qf<Function>::type function; 117 template<typename Sig> 118 struct result; 119 template<typename Self,typename Seq> 120 struct result<Self const (Seq &)> 121 : boost::result_of< function_c (Seq &) >{}; 122 template<typename Self,typename Seq> 123 struct result<Self (Seq &)> 124 : boost::result_of< function (Seq &) >{}; 125 }; 126 } 127 128 template <class Function, bool AllowNullary = true> 129 class unfused 130 : public unfuse_interface< 131 unfused<Function,AllowNullary>, 132 typename detail::fused_result<Function>::template result, 133 AllowNullary>{ 134 typedef typename detail::call_param<Function>::type func_const_fwd_t; 135 public: 136 inline explicit unfused(func_const_fwd_t f = function()) 137 : fnc_transformed(f) 138 { } 139 private: 140 Function fnc_transformed; 141 template<class,template<typename> class,bool> 142 friend class unfuse_interface; 143 template<typename Seq> 144 typename detail::fused_result<Function>::template result<unfused (Seq &)>::type 145 call(Seq &seq){ 146 return fnc_transformed(seq); 147 } 148 template<typename Seq> 149 typename detail::fused_result<Function>::template result<unfused const (Seq &)>::type 150 call(Seq &seq) const{ 151 return fnc_transformed(seq); 152 } 153 154 }; 155 95 156 }} 96 157 97 158 #if defined (BOOST_MSVC) 98 159 # pragma warning(pop) 99 160 #endif 100 161 101 namespace boost102 {103 template<class F>104 struct result_of< boost::fusion::unfused<F> const () >105 {106 typedef typename boost::fusion::unfused<F>::call_const_0_result type;107 };108 template<class F>109 struct result_of< boost::fusion::unfused<F>() >110 {111 typedef typename boost::fusion::unfused<F>::call_0_result type;112 };113 }114 115 162 #define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_HPP_INCLUDED 116 163 #else // defined(BOOST_PP_IS_ITERATING) 117 164 //////////////////////////////////////////////////////////////////////////////// … … 122 169 #define N BOOST_PP_ITERATION() 123 170 124 171 template <class Self, BOOST_PP_ENUM_PARAMS(N,typename T)> 125 struct result< Self const(BOOST_PP_ENUM_PARAMS(N,T)) >126 : boost::result_of< function_c(172 struct result< Self (BOOST_PP_ENUM_PARAMS(N,T)) > 173 : Result< Self ( 127 174 BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, 128 175 typename detail::mref<T,>::type BOOST_PP_INTERCEPT) > & )> 129 176 { }; 130 177 131 template <class Self, BOOST_PP_ENUM_PARAMS(N,typename T)> 132 struct result< Self(BOOST_PP_ENUM_PARAMS(N,T)) > 133 : boost::result_of< function( 134 BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, 135 typename detail::mref<T,>::type BOOST_PP_INTERCEPT) > & )> 136 { }; 137 178 //const interface, non-const arguments 138 179 template <BOOST_PP_ENUM_PARAMS(N,typename T)> 139 inline typename boost::result_of<function_c(BOOST_PP_CAT(fusion::vector,N) 140 <BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)> & )>::type 180 inline typename result< Derived const (BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type 141 181 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const 142 182 { 143 183 BOOST_PP_CAT(fusion::vector,N)< 144 184 BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > 145 arg(BOOST_PP_ENUM_PARAMS(N,a)); 146 return this->fnc_transformed(arg);185 arg(BOOST_PP_ENUM_PARAMS(N,a)); 186 return static_cast<Derived const *>(this)->call(arg); 147 187 } 148 188 189 //non-const interface, non-const arguments 149 190 template <BOOST_PP_ENUM_PARAMS(N,typename T)> 150 inline typename boost::result_of<function(BOOST_PP_CAT(fusion::vector,N) 151 <BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)> & )>::type 191 inline typename result< Derived (BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type 152 192 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) 153 193 { 154 194 BOOST_PP_CAT(fusion::vector,N)< 155 195 BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > 156 196 arg(BOOST_PP_ENUM_PARAMS(N,a)); 157 return this->fnc_transformed(arg);197 return static_cast<Derived *>(this)->call(arg); 158 198 } 199 200 //const interface, const arguments 201 template <BOOST_PP_ENUM_PARAMS(N,typename T)> 202 inline typename result< Derived const (BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT)) >::type 203 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & a)) const 204 { 205 BOOST_PP_CAT(fusion::vector,N)< 206 BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT) > 207 arg(BOOST_PP_ENUM_PARAMS(N,a)); 208 return static_cast<Derived const *>(this)->call(arg); 209 } 210 211 //non-const interface, const arguments 212 template <BOOST_PP_ENUM_PARAMS(N,typename T)> 213 inline typename result< Derived (BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT)) >::type 214 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & a)) 215 { 216 BOOST_PP_CAT(fusion::vector,N)< 217 BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT) > 218 arg(BOOST_PP_ENUM_PARAMS(N,a)); 219 return static_cast<Derived *>(this)->call(arg); 220 } 159 221 #undef N 160 222 #endif // defined(BOOST_PP_IS_ITERATING) 161 223 #endif