
On Jun 2, 2:01 pm, alfC <alfredo.cor...@gmail.com> wrote:
Hi, I need some complex arithmetic in lambda expressions, for that I implemented this to make some std::complex functions work with Boost.Lambda. ... 2) it seem imposible to generalized to other template overloads of imag<T>, real<T> (i.e. something that can be used for std::complex<T>) because the template parameter Arg doesn't have information about the actual type. is it so?
I think I now appreciate what Joel DG. refers to when he says that bind functions are monomorphic, and why they cannot do what I pointed in 2). The following is the Phoenix equivalent, i.e. the code that makes std::complex play well with Phoenix, moreover it is truly polymorphic, they work for all std::complex<T> types, (in fact it should work for any type that has the nested type ::value_type) #ifndef BOOST_PHOENIX_COMPLEX_HPP #define BOOST_PHOENIX_COMPLEX_HPP #include<boost/spirit/home/phoenix.hpp> #include<complex> namespace boost{ namespace phoenix{ #define BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( FunctionnamE ) \ struct FunctionnamE##_eval{ \ template <typename Env, typename Arg_> struct result{typedef typename boost::mpl::at_c<typename Env::args_type, 0>::type::value_type type;}; \ template <typename RT, typename Env, typename Arg_> static RT eval(Env const& env, Arg_ const& arg_){ \ return FunctionnamE(arg_.eval(env)); \ } \ }; \ template <typename Arg_> actor<typename as_composite<FunctionnamE##_eval, Arg_>::type> \ FunctionnamE(Arg_ const& arg_){ \ return compose<FunctionnamE##_eval>(arg_); \ } //as listed in http://www.cplusplus.com/reference/std/complex/ BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( real ) BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( imag ) BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( abs ) BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( norm ) BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL( arg ) //argument complex function, do not confuse with arg_ #undef BOOST_PHOENIX_UNARY_COMPLEX_TO_REAL #define BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( FunctionnamE ) \ struct FunctionnamE##_eval{ \ template <typename Env, typename Arg_> struct result{typedef typename boost::mpl::at_c<typename Env::args_type, 0>::type type;}; \ template <typename RT, typename Env, typename Arg_> static RT eval(Env const& env, Arg_ const& arg_){ \ return FunctionnamE(arg_.eval(env)); \ } \ }; \ template <typename Arg_> actor<typename as_composite<FunctionnamE##_eval, Arg_>::type> \ FunctionnamE(Arg_ const& arg_){ \ return compose<FunctionnamE##_eval>(arg_); \ } BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( conj ) //todo: polar BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( cos ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( cosh ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( exp ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( log ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( log10 ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( pow ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( sin ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( sinh ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( sqrt ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( tan ) BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX( tanh ) #undef BOOST_PHOENIX_UNARY_COMPLEX_TO_COMPLEX }} #endif