Problem with Phoenix v2

Mathias Gaunard <[email protected]> Wed, 02 Feb 2011 16:38:37 +0100
Newsgroups gmane.comp.parsers.spirit.devel
Message-ID <[email protected]>
The attached testcase demonstrates a problem with Phoenix v2.

The deduced type passed to apply_nary is bool, even though it should be 
an iterator_range of filter_iterator.

The testcase works correctly with Phoenix v3.

The non-functional version is also provided for reference and testing.

The testcase is available both as a fully functional version and a 
somewhat simplified version because when I explained the problem to 
Thomas Heller he claimed the problems were due to nested lambdas or 
rvalues, which isn't the case.

------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

_______________________________________________
Spirit-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
test.cpp (text/x-c++src, 1.9 KB)
#if 1 // Phoenix v2
#include <boost/spirit/home/phoenix/core.hpp>
#include <boost/spirit/home/phoenix/operator.hpp>
#include <boost/spirit/home/phoenix/statement.hpp>
#include <boost/spirit/home/phoenix/object.hpp>
#include <boost/spirit/home/phoenix/stl.hpp>
#include <boost/spirit/home/phoenix/scope.hpp>
#include <boost/spirit/home/phoenix/function.hpp>
#else // Phoenix v3
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/statement.hpp>
#include <boost/phoenix/object.hpp>
#include <boost/phoenix/stl.hpp>
#include <boost/phoenix/scope.hpp>
#include <boost/phoenix/function.hpp>
#endif

#include <boost/range/adaptor/filtered.hpp>
#include <boost/function.hpp>

#include <vector>
#include <iostream>

namespace phoenix = boost::phoenix;
using namespace phoenix::arg_names;

typedef std::vector<int> expression;

struct apply_nary_impl
{
    template<typename A>
    struct result
    {
        typedef expression type;
    };
    
    template<typename Range>
    expression operator()(const Range& range) const
    {
        return range.front(); // to make error visible
    }
};

static phoenix::function<apply_nary_impl> apply_nary;

int main()
{
    std::vector<expression> v(10);
    v[3] = expression(1);

    boost::function<bool(const expression&)> f2 = !phoenix::empty(_1);
    
    boost::range_detail::filter_holder<
        boost::function<bool(const expression&)>
    > filter = boost::adaptors::filtered(f2);


#if 0 // non-functional version

    expression e = apply_nary_impl()(v | filter);
    
#elif 1 // partially functional version

    boost::function<expression(const std::vector<expression>&)> f
        = apply_nary(_1 | phoenix::val(filter));
        
    expression e = f(v);
    
#else // fully functional version

    expression e = apply_nary(_1 | phoenix::val(boost::adaptors::filtered(!phoenix::empty(_1))))(v);
    
#endif 

    // should display 1
    std::cout << e.size() << std::endl;
}