Boost logo

Boost Users :

Subject: [Boost-users] Please help with metaprogramming question : termination of recursion
From: John Dlugosz (JDlugosz_at_[hidden])
Date: 2010-07-08 20:27:29


I'm using Fusion to create a list of Range objects. Here is a simple function:

                using namespace boost::fusion;

                template <typename STLCollection, typename FusB, typename FusE>
                void process_append (STLCollection& collection, const FusB& begin, const FusE& end)
                   {
                   std::cout << "Yip! ";
                   typename result_of::deref<FusB>::type r= deref(begin);
/*23*/ collection.insert (collection.end(), boost::begin(r), boost::end(r));
                   typename result_of::next<FusB>::type successor= next(begin);
/*25*/ if (successor != end) process_append (collection, successor, end);
                   std::cout << "Yap! ";
                   }

I expect it to print Yip! n times and then Yap! n times. What I get is a compiler error concerning the boost::begin(r) or boost::end(r), that I'm calling it on a fusion::void_ rather than a Range. As you see, I have moved the end-of-recusion test from its normal position at the top of the function (test when called, and return immediately rather than doing the normal body) to the point of the recursive call (don't call with the end sentinel). However, this appears to still trigger the function expansion, since the trail of errors seems to go from the point marked 23 as the original (inner-most) error, to several stops at point 25, to the caller, and so on back out. So it expands several times and then errors, so I think it is objecting to the "end" case.

Now if simply mentioning the function, not calling it, is enough to make it expand the function, then more levels of indirection isn't going to help. What is the proper way to do this? Is there, somewhere, a proper example of using Fusion to iterate from begin to end of a Fusion collection? Presumably this must be done using recursion because the type of "next(I)" is not necessarily the same as the type of "I".

If some other kind of overloading or partial specialization is the trick, I would expect that the "end" type, or the dereference of the "end" type, would be documented as something I could easily use for that.

Please help.
Thanks in advance,

--John


2>D:\boost_1_43_0\boost/range/iterator.hpp(63) : error C2039: 'type' : is not a member of 'boost::mpl::eval_if_c<C,F1,F2>'
2> with
2> [
2> C=true,
2> F1=boost::range_const_iterator<boost::fusion::void_>,
2> F2=boost::range_mutable_iterator<const boost::fusion::void_>
2> ]
2> blahblahblah.h(23) : see reference to class template instantiation 'boost::range_iterator<C>' being compiled
2> with
2> [
2> C=const boost::fusion::void_
2> ]
2> blahblahblah.h(25) : see reference to function template instantiation 'void Aa::catranges_help::process_append<STLCollection,boost::fusion::cons_iterator<const boost::fusion::nil>,FusE>(STLCollection &,const FusB &,const FusE &)' being compiled
2> with
2> [
2> STLCollection=std::vector<RTPRICEREC>,
2> FusE=boost::fusion::cons_iterator<const boost::fusion::nil>,
2> FusB=boost::fusion::cons_iterator<const boost::fusion::nil>
2> ]
2> blahblahblah.h(25) : see reference to function template instantiation 'void Aa::catranges_help::process_append<STLCollection,boost::fusion::cons_iterator<Cons>,FusE>(STLCollection &,const FusB &,const FusE &)' being compiled
2> with
2> [
2> STLCollection=std::vector<RTPRICEREC>,
2> Cons=const boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>,
2> FusE=boost::fusion::cons_iterator<const boost::fusion::nil>,
2> FusB=boost::fusion::cons_iterator<const boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>>
2> ]
2> blahblahblah.h(25) : see reference to function template instantiation 'void Aa::catranges_help::process_append<STLCollection,boost::fusion::cons_iterator<Cons>,FusE>(STLCollection &,const FusB &,const FusE &)' being compiled
2> with
2> [
2> STLCollection=std::vector<RTPRICEREC>,
2> Cons=const boost::fusion::cons<std::vector<RTPRICEREC>,boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>>,

2> FusE=boost::fusion::cons_iterator<const boost::fusion::nil>,
2> FusB=boost::fusion::cons_iterator<const boost::fusion::cons<std::vector<RTPRICEREC>,boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>>>
2> ]
2> blahblahblah.h(55) : see reference to function template instantiation 'void Aa::catranges_help::process_append<std::vector<_Ty>,boost::fusion::cons_iterator<Cons>,boost::fusion::cons_iterator<const boost::fusion::nil>>(STLCollection &,const FusB &,const FusE &)' being compiled
2> with
2> [
2> _Ty=RTPRICEREC,
2> Cons=const boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::cons<std::vector<RTPRICEREC>,boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>>>,
2> STLCollection=std::vector<RTPRICEREC>,
2> FusB=boost::fusion::cons_iterator<const boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::cons<std::vector<RTPRICEREC>,boost::fusion::cons<std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,boost::fusion::nil>>>>,
2> FusE=boost::fusion::cons_iterator<const boost::fusion::nil>
2> ]
2> blahblahblah.h(53) : while compiling class template member function 'Aa::catranges_help::object<R,Tail>::operator std::vector<_Ty>(void) const'
2> with
2> [
2> R=std::pair<std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>,std::_Vector_const_iterator<RTPRICEREC,std::allocator<RTPRICEREC>>>,
2>

TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.


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