Boost logo

Boost Users :

Subject: Re: [Boost-users] [lambda][phoenix] make lambda/phoenix play well with std::complex, imag, real, abs, etc.
From: Joel de Guzman (joel_at_[hidden])
Date: 2010-06-06 19:41:26


On 6/6/10 10:10 AM, alfC wrote:
> On Jun 2, 2:01 pm, alfC<alfredo.cor..._at_[hidden]> 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

Is there a reason why you are not using plain phoenix::function(s)
for this?

Regards,

-- 
Joel de Guzman
http://www.boostpro.com
http://spirit.sf.net

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net