Opened 9 years ago

Closed 9 years ago

#9840 closed Bugs (invalid)

phoenix V3 and stl container non const methods

Reported by: Theodore.Papadopoulo@… Owned by: Thomas Heller
Milestone: To Be Determined Component: phoenix
Version: Boost 1.53.0 Severity: Problem
Keywords: stl container method Cc:

Description

I'm using boost 1.53 (boost-devel-1.53.0-6.fc19.i686). I think I found a bug with phoenix and stl methods. It looks like boost assumes that all methods are const which is not true (eg vector::reserve).

I tried to change:

#define BOOST_PHOENIX_ADAPT_CALLABLE(NAME, FUNC, N)                             \
    template <BOOST_PHOENIX_typename_A(N)>                                      \
    inline                                                                      \
    typename                                                                    \
        boost::phoenix::detail::expression::function_eval<                      \
            FUNC                                                                \
          , BOOST_PHOENIX_A(N)>::type const                                     \
    NAME(BOOST_PHOENIX_A_const_ref_a(N))                                        \
    {                                                                           \
        return boost::phoenix::detail::expression::                             \
            function_eval<FUNC, BOOST_PHOENIX_A(N)>::                           \
                make(FUNC(), BOOST_PHOENIX_a(N));                               \
    }                                                                           \

into

#define BOOST_PHOENIX_ADAPT_CALLABLE(NAME, FUNC, N)                             \
    template <BOOST_PHOENIX_typename_A(N)>                                      \
    inline                                                                      \
    typename                                                                    \
        boost::phoenix::detail::expression::function_eval<                      \
            FUNC                                                                \
          , BOOST_PHOENIX_A(N)>::type const                                     \
    NAME(BOOST_PHOENIX_A_ref_a(N))                                        \
    {                                                                           \
        return boost::phoenix::detail::expression::                             \
            function_eval<FUNC, BOOST_PHOENIX_A(N)>::                           \
                make(FUNC(), BOOST_PHOENIX_a(N));                               \
    }                                                                           \

but that's not enough. That part of the problem remains in git. But that is not sufficient, some other method in the chain imposes constness.

phoenix should not try to impose constness IMHO, the chain of instantiations should just pass the orginal type...

Here is a (not totally simplified as it uses spirit) example to reproduce the problem:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/phoenix/stl.hpp>
#include <boost/spirit/include/qi_uint.hpp>
#include <boost/phoenix/phoenix.hpp>

std::vector<unsigned> L;

int
main() {
    using namespace boost::spirit::qi;
    using namespace boost::phoenix;
    using boost::phoenix::arg_names::_1;
    const std::string str("3 1 2 3");
    std::string::const_iterator first = str.begin();
    parse(first,str.end(), uint_[reserve(L,_1)] >> repeat(capacity(L))[ uint_ ]);

}

Attachments (1)

test.C (529 bytes ) - added by Theodore.Papadopoulo@… 9 years ago.
File to reproduce the problem

Download all attachments as: .zip

Change History (6)

by Theodore.Papadopoulo@…, 9 years ago

Attachment: test.C added

File to reproduce the problem

comment:1 by Theodore.Papadopoulo@…, 9 years ago

I forgot, this is to be compiled with:

g++ -DBOOST_SPIRIT_USE_PHOENIX_V3 test.C

comment:2 by Joel de Guzman, 9 years ago

Please post a test cpp file that does not use Spirit. A phoenix-only test will make it clear that this is a phoenix bug, if it is indeed a bug.

comment:3 by Theodore Papadopoulo <Theodore.Papadopoulo@…>, 9 years ago

I cannot, I tried some obvious code, but I do not know phoenix much. Can you requalify it as a spirit bug ?

comment:4 by Joel de Guzman, 9 years ago

Wait, I see the problem and it's not a phoenix bug nor a spirit bug. It's a usage bug.

1) L is captured by value, by default. Use ref if you want to capture by reference 2) Use boost::spirit::qi::_1 instead of boost::phoenix::arg_names::_1

Here's the working code:

    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <boost/phoenix/stl.hpp>
    #include <boost/spirit/include/qi_uint.hpp>
    #include <boost/phoenix/phoenix.hpp>

    std::vector<unsigned> L;

    int
    main() {
        using namespace boost::spirit::qi;
        using namespace boost::phoenix;
        using boost::spirit::qi::_1;
        namespace phx = boost::phoenix;
        const std::string str("3 1 2 3");
        std::string::const_iterator first = str.begin();
        parse(first,str.end(), uint_[reserve(phx::ref(L),_1)] >> repeat(capacity(phx::cref(L)))[ uint_ ]);
    }

I'll leave it up to you to close this ticket.

comment:5 by Joel de Guzman, 9 years ago

Resolution: invalid
Status: newclosed

I'm closing this one. Feel free to re-open if you have objections.

Note: See TracTickets for help on using tickets.