[Boost-bugs] [Boost C++ Libraries] #8704: Using Phoenix lambdas on top of custom Proto expressions

Subject: [Boost-bugs] [Boost C++ Libraries] #8704: Using Phoenix lambdas on top of custom Proto expressions
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-06-17 19:55:54


#8704: Using Phoenix lambdas on top of custom Proto expressions
------------------------------+---------------------
 Reporter: ddemidov@… | Owner: theller
     Type: Patches | Status: new
Milestone: To Be Determined | Component: phoenix
  Version: Boost 1.53.0 | Severity: Problem
 Keywords: phoenix proto |
------------------------------+---------------------
 Some prehistory:

 I am working on VexCL (https ://github.com/ddemidov/vexcl) - a vector
 expression template library for OpenCL. I have recently added support for
 automatic generation of OpenCL kernels from generic functors (description
 of the feature: https ://github.com/ddemidov/vexcl#function-generator).

 In order to implement this, I pass the instances of vex::symbolic<T> class
 to the given functor. vex::symbolic<T> dumps to output stream any
 arithmetic operations it is being subjected to, and that's how I am able
 to construct the OpenCL kernel source. The symbolic<T> class is of course
 a Boost.Proto terminal.



 Now, it seems natural to use Boost.Phoenix to provide the generic functors
 for the function generator. And indeed it is possible with simple
 expressions (see https
 ://github.com/ddemidov/vexcl/blob/a95dfdd68/tests/generator.cpp#L124).
 However, if I try to bring cmath functions overloads from
 <boost/phoenix/stl/cmath.hpp> and use those (https
 ://github.com/ddemidov/vexcl/commit/b95da14e51), I get compilation errors.
 The reason apparently is that boost::phoenix_impl::<function>_impl assumes
 that result of <function>(expr) has the same type as expr itself. This of
 course is not true if expr is a Boost.Proto expression.

 Everything works as intended with the following patch:

 {{{
 --- a/cmath.hpp
 +++ b/cmath.hpp
 @@ -25,11 +25,11 @@ namespace boost {
          struct result<This(BOOST_PHOENIX_A(n))> \
          { \
              typedef \
 - typename proto::detail::uncvref<A0>::type \
 + decltype( name(typename
 proto::detail::uncvref<A0>::type()) ) \
                  type; \
          }; \
          template<BOOST_PHOENIX_typename_A(n)> \
 - A0 operator()(BOOST_PHOENIX_A_const_ref_a(n)) const { \
 + auto operator()(BOOST_PHOENIX_A_const_ref_a(n)) const ->
 decltype( name(BOOST_PHOENIX_a(n)) ) { \
              using namespace std; \
              return name(BOOST_PHOENIX_a(n)); \
          } \
 }}}
 I understand this is unacceptable in its current form (because it uses
 c++11 features), but I could not come up with other solution (e.g. in
 terms of boost::result_of).

 Sorry for the broken links, Trac did not allow me to submit otherwise.
 Best regards,
 Denis

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8704>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC