Setting the qi::_pass flag in a phoenix function called from a semantic action

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Setting the qi::_pass flag in a phoenix function called from a semantic action

davew

Hello,

I have been using Spirit for a while now but recently hit a problem when compiling with C++ 11 support.

My platform is OS X and my compiler is Apple's version of clang.

The compiler details are:

Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)

I am using a Phoenix function which is called from a semantic action.

The parameters to the function are the parsed value, along with the qi::_pass flag.

The flag is passed by reference so that the function can set it to true or false as appropriate, depending
on the parsed value.

I have produced a simple test program that illustrates the problem.
The test program is attached to this email.

The operator inside the phoenix function looks like this:
-------------------------------------------------------------------------
int operator()(int a, bool& flag) const
{
        std::cout << "Called int operator()(int a, bool& flag), a=" << a << std::endl;

        if (a == 11)
                flag=false;
        else
                flag=true;

        return a + _value;
}
-------------------------------------------------------------------------

The rule looks like this:
-------------------------------------------------------------------------
   // Define the parser rule.
   qi::rule<
      std::string::const_iterator,
      int(),                    // The rule returns an int value (accessible as _val)
      ascii::space_type
   >
     
   intRule =  qi::int_[qi::_val = add_int(qi::_1, qi::_pass)];
 -------------------------------------------------------------------------  
   
The name of the phoenix function is add_int, which is invoked with the parsed int value and the qi::_pass flag.

This compiles and works fine as a C++ 98 program.

However when I try to compile with C++ 11 support I get an error which suggests that the flag should be passed
as a const reference.

The compile error log contains the following lines:

 -------------------------------------------------------------------------  
In file included from /Users/davew/Documents/boost_1_59_0/boost/phoenix/core/detail/preprocessed/function_eval.hpp:12:
/Users/davew/Documents/boost_1_59_0/boost/phoenix/core/detail/preprocessed/function_eval_10.hpp:121:52: error: no type named 'type' in 'boost::result_of<const add_int_impl (int &, const bool &)>'
                    boost::result_of<fn(a0 , a1)>::type
 -------------------------------------------------------------------------  
 
If I change the flag to be a const reference then the program compiles OK (if I also remove the code that modifies the flag).

Of course if the reference is const then I won't be able to change it.

The problem appears to be related to the use of boost::result_of with C++ 11.
As I understand it boost::result_of uses the C++ 11 function decltype() to deduce the function return type
based on the function parameters. Here it is assuming that the boolean flag is a constant reference parameter.
                   
If I set the compile flag BOOST_RESULT_OF_USE_TR1 then the program compiles OK with C++ 11.

Can anyone provide any insights as to why this compiles with C++ 98 but not C++ 11 ?

Is Phoenix meant to support a function with a reference parameter that is non-const ?

Thanks,

Dave


                   

------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

spiritTestPassWithPhoenixFunction.cpp (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Setting the qi::_pass flag in a phoenix function called from a semantic action

Joel de Guzman
On 10/16/15 11:33 PM, David Williams wrote:

>
> Hello,
>
> I have been using Spirit for a while now but recently hit a problem when compiling with C++ 11 support.
>
> My platform is OS X and my compiler is Apple's version of clang.
>
> The compiler details are:
>
> Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
>
> I am using a Phoenix function which is called from a semantic action.
>
> The parameters to the function are the parsed value, along with the qi::_pass flag.
>
> The flag is passed by reference so that the function can set it to true or false as appropriate, depending
> on the parsed value.
>
> I have produced a simple test program that illustrates the problem.
> The test program is attached to this email.
>
> The operator inside the phoenix function looks like this:
> -------------------------------------------------------------------------
> int operator()(int a, bool& flag) const
> {
> std::cout << "Called int operator()(int a, bool& flag), a=" << a << std::endl;
>
> if (a == 11)
> flag=false;
> else
> flag=true;
>
> return a + _value;
> }
> -------------------------------------------------------------------------
>
> The rule looks like this:
> -------------------------------------------------------------------------
>     // Define the parser rule.
>     qi::rule<
>        std::string::const_iterator,
>        int(),                    // The rule returns an int value (accessible as _val)
>        ascii::space_type
>     >
>
>     intRule =  qi::int_[qi::_val = add_int(qi::_1, qi::_pass)];
>   -------------------------------------------------------------------------
>
> The name of the phoenix function is add_int, which is invoked with the parsed int value and the qi::_pass flag.
>
> This compiles and works fine as a C++ 98 program.
>
> However when I try to compile with C++ 11 support I get an error which suggests that the flag should be passed
> as a const reference.
>
> The compile error log contains the following lines:
>
>   -------------------------------------------------------------------------
> In file included from /Users/davew/Documents/boost_1_59_0/boost/phoenix/core/detail/preprocessed/function_eval.hpp:12:
> /Users/davew/Documents/boost_1_59_0/boost/phoenix/core/detail/preprocessed/function_eval_10.hpp:121:52: error: no type named 'type' in 'boost::result_of<const add_int_impl (int &, const bool &)>'
>                      boost::result_of<fn(a0 , a1)>::type
>   -------------------------------------------------------------------------
>
> If I change the flag to be a const reference then the program compiles OK (if I also remove the code that modifies the flag).
>
> Of course if the reference is const then I won't be able to change it.
>
> The problem appears to be related to the use of boost::result_of with C++ 11.
> As I understand it boost::result_of uses the C++ 11 function decltype() to deduce the function return type
> based on the function parameters. Here it is assuming that the boolean flag is a constant reference parameter.
>
> If I set the compile flag BOOST_RESULT_OF_USE_TR1 then the program compiles OK with C++ 11.
>
> Can anyone provide any insights as to why this compiles with C++ 98 but not C++ 11 ?
>
> Is Phoenix meant to support a function with a reference parameter that is non-const ?

I'll forward this to the Fusion maintainers.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Setting the qi::_pass flag in a phoenix function called from a semantic action

Joel de Guzman
On 10/20/15 8:14 AM, Joel de Guzman wrote:
>
> I'll forward this to the Fusion maintainers.

Sorry, disregard that. It's not a fusion problem. I initially thought it was,
since we're working on Fusion and boost::result_of and Fusion recently.
I'm looking into it.

regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Setting the qi::_pass flag in a phoenix function called from a semantic action

Joel de Guzman
On 10/20/15 8:20 AM, Joel de Guzman wrote:
> On 10/20/15 8:14 AM, Joel de Guzman wrote:
>>
>> I'll forward this to the Fusion maintainers.
>
> Sorry, disregard that. It's not a fusion problem. I initially thought it was,
> since we're working on Fusion and boost::result_of and Fusion recently.
> I'm looking into it.

OK, it appears to be the long standing bug on Phoenix that relates to
sfinae-friendly boost::result_of. Could you please file a bug report
to Phoenix? Thomas Heller is no longer maintaining Phoenix. John Fletcher
is the current maintainer, but he's also not that active really. I
guess I'll have to pick it up again, if he does not.

In the meantime, you know the workaround: BOOST_RESULT_OF_USE_TR1

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Setting the qi::_pass flag in a phoenix function called from a semantic action

davew
Hi Joel,

Thanks for your help with this.

I have raised a bug report which has ticket #11705.
I have given it the catchy title 'Phoenix function defining operator() with non-const reference parameter fails to compile with C++ 11.'

Best regards,

Dave

On 20 Oct 2015, at 01:35, Joel de Guzman <[hidden email]> wrote:

> On 10/20/15 8:20 AM, Joel de Guzman wrote:
>> On 10/20/15 8:14 AM, Joel de Guzman wrote:
>>>
>>> I'll forward this to the Fusion maintainers.
>>
>> Sorry, disregard that. It's not a fusion problem. I initially thought it was,
>> since we're working on Fusion and boost::result_of and Fusion recently.
>> I'm looking into it.
>
> OK, it appears to be the long standing bug on Phoenix that relates to
> sfinae-friendly boost::result_of. Could you please file a bug report
> to Phoenix? Thomas Heller is no longer maintaining Phoenix. John Fletcher
> is the current maintainer, but he's also not that active really. I
> guess I'll have to pick it up again, if he does not.
>
> In the meantime, you know the workaround: BOOST_RESULT_OF_USE_TR1
>
> Regards,
> --
> Joel de Guzman
> http://www.ciere.com
> http://boost-spirit.com
> http://www.cycfi.com/
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Spirit-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/spirit-general


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general