Boost logo

Boost Users :

Subject: Re: [Boost-users] [fusion] Are Sequence stream IO operators recursive?
From: Hugh Dickinson (Hugh.Dickinson_at_[hidden])
Date: 2010-11-03 07:04:51


On 3 Nov 2010, at 00:44, Joel de Guzman wrote:
> On 11/3/10 7:23 AM, Hugh Dickinson wrote:
>> On 2 Nov 2010, at 20:05, OvermindDL1 wrote:
>>
>>> On Tue, Nov 2, 2010 at 4:31 AM, Hugh Dickinson <hugh.dickinson_at_[hidden]> wrote:
>>>> I'm trying to output an adapted fusion sequence
>>>> (PMT::QE::DataSet<PMT::QE::Measurement>) containing other adapted fusion sequences
>>>> to std::cout. I had hoped for recursive behaviour, such that the contents of each
>>>> sub-sequence are printed in turn. Having looked at the code in
>>>> $BOOST_ROOT/boost/fusion/sequence/io/detail/out.hpp it looks like:
>>>>
>>>> ---- PMT::QE::DataSet<PMT::QE::Measurement> output;
>>>>
>>>> ... Fill output ...
>>>>
>>>> std::cout<< output<< std::endl; ----
>>>>
>>>> should work. Unfortunately, I'm getting compilation errors like:
>>>>
>>>> no match for ‘operator<<’ in ‘os<< boost::fusion::operator* [with Iterator =
>>>> boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag,
>>>> boost::fusion::assoc_struct_category, const PMT::QE::DataSet<PMT::QE::Measurement>,
>>>> 0>](((const
>>>> boost::fusion::iterator_base<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag,
>>>> boost::fusion::assoc_struct_category, const PMT::QE::DataSet<PMT::QE::Measurement>,
>>>> 0> >&)((const
>>>> boost::fusion::iterator_base<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag,
>>>> boost::fusion::assoc_struct_category, const PMT::QE::DataSet<PMT::QE::Measurement>,
>>>> 0> >*)((const boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag,
>>>> boost::fusion::assoc_struct_category, const PMT::QE::DataSet<PMT::QE::Measurement>,
>>>> 0>*)first))))’
>>>>
>>>> The other errors simply replace the index 0 with 1 and 2 (PMT::QE::DataSet has 3
>>>> elements). On the other hand, the following does work:
>>>>
>>>> ---- PMT::QE::DataSet<PMT::QE::Measurement> output;
>>>>
>>>> ... Fill output ...
>>>>
>>>> std::cout<< at_c<0>(output)<< std::endl; std::cout<< at_c<1>(output)<<
>>>> std::endl; std::cout<< at_c<2>(output)<< std::endl;
>>>>
>>>> ----
>>>>
>>>> Is this the expected behaviour? What am I missing? Is there a way to achieve the
>>>> desired recursive behaviour?
>>>>
>>>> Many thanks,
>>>
>>> You have included<boost/fusion/includes/io.hpp>, right? Without that then output
>>> would generate an error like the above if output is a fusion sequence, else it should
>>> stream out fine.
>>
>> Thanks for the reply. In answer to your question, yes, I've included that header. What
>> confuses me the most is that the second example I gave works just fine, listing the
>> contents of each of the 3 elements of "output".
>>
>> To offer some more (probably useless) information, I had not adapted the specialisation
>> of PMT::QE::DataSet<PMT::QE::Measurement> but rather the generic PMT::QE::DataSet<T>
>> using BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT. Since originally posting I've also tried
>> adapting the specialisation and also making PMT::QE::DataSet an ordinary non-template
>> struct and adapting that with BOOST_FUSION_ADAPT_ASSOC_STRUCT. In all cases, I get the
>> same error.
>>
>> Maybe this will help track down the problem.
>
> From the error message, I'm guessing that you are adapting a struct to
> fusion. Fusion is not picking the right overload for your struct.
> In the second case, you are in the right namespace and ADL is kicking
> in just fine. Try providing a << overload in the namespace of your struct.
>
> Regards,
> --
> Joel de Guzman
> http://www.boostpro.com
> http://spirit.sf.net
>
Hi Joel, thanks for the reply. I don't really understand what you mean, could you explain in a bit more detail. I would have thought that since PMT::QE::DataSet is a fusion sequence, then the overload defined in boost/fusion/sequence/io/detail/out.hpp should have been selected. The macro calls to adapt the struct and it's elements are called in the global namespace (after I changed DataSet to be a non-template class) as follows:

BOOST_FUSION_ADAPT_ASSOC_STRUCT(PMT::QE::Measurement,
(PMT::QE::Wavelength::type, wavelength, PMT::QE::Wavelength)
(PMT::QE::TestCurrent::type, testCurrent, PMT::QE::TestCurrent)
(PMT::QE::RefCurrent::type, refCurrent, PMT::QE::RefCurrent)
)

BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(CurrentType),
(PMT::QE::Pedestals) (CurrentType),
(typename CurrentType::type, startPedestal, PMT::QE::Start)
(typename CurrentType::type, endPedestal, PMT::QE::End)
)

BOOST_FUSION_ADAPT_ASSOC_STRUCT(
PMT::QE::DataSet,
(std::vector<PMT::QE::Measurement>, measurements, PMT::QE::Measurements)
(PMT::QE::Pedestals<PMT::QE::TestCurrent>, testPedestal, PMT::QE::TestPedestal)
(PMT::QE::Pedestals<PMT::QE::RefCurrent>, refPedestal, PMT::QE::RefPedestal)
)

I have also defined an overload of operator<< for std::vector<T> in the global namespace, allowing the explicit streaming out of the individual elements of DataSet to work.

Anyway, if you could elaborate on your suggestion it would be very helpful.

Thanks,

Hugh

>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


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