"David Abrahams" <dave@boost-consulting.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
Hi,
I am trying to transform from a fusion vector of values to a fusion vector of non-const references to those values, the ultimate aim being to assign the original sequence from another sequence.
The code below works ok with make_vector, but I want to be able to automate it for any fusion sequence. How can I do that?
You can find an example of exactly that on the zip_iterator_fusion branch of boost/iterator/zip_iterator.hpp
Yikes. I don't really understand what I am meant to do with that. I will have to study it in more detail. I reckon that a get_ref_vector(fusion::vector) would be quite useful. I guess there isnt much difference to a view though?. Anyway I have continued hacking away and so here is my latest efforts, using fusion to do a dot product of two vectors. Maybe it would be a useful example in the fusion docs?. Anyway here it is FWIW: regards Andy Little -------------------------- // Copyright Andrew Little 2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See QUAN_ROOT/quan_matters/index.html for documentation. /* dot product of two vectors using fusion. The input vectors are just raw fusion sequences */ #include <quan/out/length.hpp> #include <quan/out/reciprocal_length.hpp> #include <quan/operators/binary_operator_functors.hpp> #include <boost/fusion/sequence/container/vector.hpp> #include <boost/fusion/sequence/conversion/as_vector.hpp> #include <boost/fusion/sequence/intrinsic/at.hpp> #include <boost/fusion/sequence/intrinsic/value_at.hpp> #include <boost/fusion/algorithm/transformation/transform.hpp> #include <boost/fusion/algorithm/iteration/fold.hpp> #include <boost/ref.hpp> #include <cassert> // Couldnt resist this... :-) namespace quan{ namespace fusion{ // This functor needed as fusion::fold sends // its args the opposite way to quan::operator_XX_equals // Lhs in invoked function is assumed to be // a non const boost::reference_wrapper template <typename F> struct reverse_assign_f_args{ template <typename Rhs, typename Lhs> struct result{ BOOST_MPL_ASSERT((boost::is_reference_wrapper<Lhs>)); BOOST_MPL_ASSERT((boost::mpl::not_< boost::is_const<typename Lhs::type> >)); typedef Lhs type; }; template <typename Rhs, typename Lhs> typename result<Rhs,Lhs>::type operator()( Rhs const & rhs, Lhs lhs)const { F f; return boost::ref(f(lhs.get(),rhs)); } }; // more arg reversing template <typename F> struct reverse_f_args{ template <typename Rhs, typename Lhs> struct result{ typedef typename F:: template result< Rhs,Lhs >::type type; }; template <typename Rhs, typename Lhs> typename result<Rhs,Lhs>::type operator()( Rhs const & rhs, Lhs const & lhs )const { F f; f(lhs,rhs); } }; }}//quan::fusion int main() { // The types of the input 'vectors' typedef boost::fusion::vector4< quan::length::mm,int,int,int > seq1_type; typedef boost::fusion::vector4< quan::reciprocal_length::per_m,int,int,int > seq2_type; // Use fusion to work out the type of the result of // the dot product... // First the result sequence of // multiplying the input sequences. typedef boost::fusion::result_of::as_vector< boost::fusion::result_of::transform< seq1_type,seq2_type,quan::operator_times >::type >::type multiplied_seq; // Now the add and accumulate result type deduction part. // Note that need to switch the args for use with my own functors, // (I have been here with boost::is_convertible, so I'll say no more;-)). // I am using + as the 2nd function applied, not +=, as used at runtime // as I am also trying to 'accumulate' the result_type at this stage. typedef boost::fusion::result_of::fold< multiplied_seq, boost::fusion::result_of::at_c<multiplied_seq,0>::type , quan::fusion::reverse_f_args<quan::operator_plus> >::type result_type; // There was a bit of fun and games to get here so ... BOOST_STATIC_ASSERT(( boost::is_same<result_type,double>::value !=0)); // set up the input 'vectors' seq1_type seq1(quan::length::mm(1000),2,3,4); seq2_type seq2(quan::reciprocal_length::per_m(1),2,3,4); // do the dot_product result_type result = boost::fusion::fold( boost::fusion::transform(seq1,seq2,quan::operator_times()), boost::ref(result), quan::fusion::reverse_assign_f_args<quan::operator_plus_equals>() ); assert(quan::compare(result,30,1e-12) ==0); std::cout << result <<'\n'; } -----------------------------