[fusion] memory layout of fusion::vector vs boost::tuple/boost::array

Hi, I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.) #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include<boost/array.hpp> #include<iostream> #include<boost/tuple/tuple.hpp> using std::clog; using std::endl; int main(){ boost::array<double, 3> ba={{1.0, 2.1, 3.2}}; clog << "ba: " << ba[0] << ", " << ba[1] << ", " << ba[2] << endl; using namespace boost::fusion; vector<double, double, double> bfv( reinterpret_cast<vector<double, double, double>&>(ba) ); //doesn't work as expected clog << "bfv: " << at_c<0>(bfv) << ", "<< at_c<1>(bfv) << ", " << at_c<2>(bfv) << endl; using boost::tuple; tuple<double, double, double> btt(reinterpret_cast<tuple<double, double, double>&>(ba) ); // works! clog << "btt: " << btt.get<0>() << ", "<< (btt).get<1>() << ", " << (btt).get<2>() << endl; return 0; } outputs: ba: 1, 2.1, 3.2 //original data bfv: -9.25597e+61, -2.35344e-185, 4.87507e-270 //not expected btt: 1, 2.1, 3.2 //works! Let me give some context, the reason I am doing this is that I need to interface fusion::vector of boost::quantities (all have the sizeof double) and adimensionalize the list of quantities into an array of doubles and vise-versa In reality, the final goal is to get this to work: boost::array<double, 3> ba={{1.0, 2.1, 3.2}}; vector<quantity<si::length>, quantity<si::time> , quantity<si::mass> > bfv( reinterpret_cast<vector<quantity<si::length>, quantity<si::time> , quantity<si::mass> >&>(ba) ); (or other generic option to go from array<double, N> to vector<quantity<T1>, quantity<T2>, ... quantity<TN> >) but since I can't make it work with simple 'doubles' I am asking why this could be done. Thank you again, Alfredo

On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On Oct 6, 5:33 pm, Joel de Guzman <j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
It is not only not guaranteed, it does not work at present. Any two cents why is that fusion::vector may (do?) implement a non obvious memory layout? I solved the problem of array<double, N> to vector<double ...>: I found the feature of the library that allows conversion from array<double, N> to vector<double*N ... >. Just by including #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> boost::array<double, 3> ba={{1.0, 2.1, 3.2}}; vector<double, double, double> bfv1(ba); //works. I still can the other way around. boost::array<double, 3> ba0(bfv1); //doesn't work ideas? great, I also managed to solve the original problem on how to convert from boost::array<double, N> to fusion::vector<quantity<T1>, quantity<T2>, ... quantity<TN> > thanks to your other posting suggesting using fusion::transform quantity<T> can be constructed from a double with quantity<T>::from_value(double) The line of code that does this is typedef boost::fusion::vector<quantity<si::length>, quantity<si::time>, quantity<si::mass> > vector_of_q; vector_of_q fvq( transform( ba, // boost::array<double, 3> // incld"/fusion/array.hpp"!! vector_of_q(), from_value() ) ); where "from_value" is defined by struct from_value{ // binary fusion transformation template <typename SignatureT> struct result; template <typename Q> struct result<from_value(double const&, Q const&)>{ typedef Q type; }; template<typename Q> Q operator()(double const& value, Q const&) const{ return Q::from_value(value); } }; I had to use the *binary* version of transform because the type of the result depends on the destination fusion::vector. The other way around from vector<quantity<T1> ... quantity<TN> > to array<double, N> should be easier (because the destination type is always double by using the quantity<T>::value() ) but I didn't managed because I didn't find the way to convert from vector<double*N> to array<double, N>. ideas? Thank you for making fusion, it is an incredible library once you realize what it is for. Alfredo

On Wed, Oct 6, 2010 at 10:54 PM, alfC <alfredo.correa@gmail.com> wrote:
On Oct 6, 5:33 pm, Joel de Guzman <j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
It is not only not guaranteed, it does not work at present. Any two cents why is that fusion::vector may (do?) implement a non obvious memory layout?
I solved the problem of array<double, N> to vector<double ...>: I found the feature of the library that allows conversion from array<double, N> to vector<double*N ... >. Just by including #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp>
boost::array<double, 3> ba={{1.0, 2.1, 3.2}}; vector<double, double, double> bfv1(ba); //works.
I still can the other way around. boost::array<double, 3> ba0(bfv1); //doesn't work ideas?
great, I also managed to solve the original problem on how to convert from boost::array<double, N> to fusion::vector<quantity<T1>, quantity<T2>, ... quantity<TN> > thanks to your other posting suggesting using fusion::transform
quantity<T> can be constructed from a double with quantity<T>::from_value(double)
The line of code that does this is
typedef boost::fusion::vector<quantity<si::length>, quantity<si::time>, quantity<si::mass> > vector_of_q; vector_of_q fvq( transform( ba, // boost::array<double, 3> // incld"/fusion/array.hpp"!! vector_of_q(), from_value() ) );
where "from_value" is defined by
struct from_value{ // binary fusion transformation template <typename SignatureT> struct result; template <typename Q> struct result<from_value(double const&, Q const&)>{ typedef Q type; }; template<typename Q> Q operator()(double const& value, Q const&) const{ return Q::from_value(value); } };
I had to use the *binary* version of transform because the type of the result depends on the destination fusion::vector.
The other way around from vector<quantity<T1> ... quantity<TN> > to array<double, N> should be easier (because the destination type is always double by using the quantity<T>::value() ) but I didn't managed because I didn't find the way to convert from vector<double*N> to array<double, N>. ideas?
Thank you for making fusion, it is an incredible library once you realize what it is for. Alfredo
You do know that based on this: http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adapted/boo... boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?

On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
On Wed, Oct 6, 2010 at 10:54 PM, alfC <alfredo.correa@gmail.com> wrote:
On Oct 6, 5:33 pm, Joel de Guzman <j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
It is not only not guaranteed, it does not work at present. Any two cents why is that fusion::vector may (do?) implement a non obvious memory layout?
I solved the problem of array<double, N> to vector<double ...>: I found the feature of the library that allows conversion from array<double, N> to vector<double*N ... >. Just by including #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp>
boost::array<double, 3> ba={{1.0, 2.1, 3.2}}; vector<double, double, double> bfv1(ba); //works.
I still can the other way around. boost::array<double, 3> ba0(bfv1); //doesn't work ideas?
great, I also managed to solve the original problem on how to convert from boost::array<double, N> to fusion::vector<quantity<T1>, quantity<T2>, ... quantity<TN> > thanks to your other posting suggesting using fusion::transform
quantity<T> can be constructed from a double with quantity<T>::from_value(double)
The line of code that does this is
typedef boost::fusion::vector<quantity<si::length>, quantity<si::time>, quantity<si::mass> > vector_of_q; vector_of_q fvq( transform( ba, // boost::array<double, 3> //
incld"/fusion/array.hpp"!!
vector_of_q(), from_value() ) );
where "from_value" is defined by
struct from_value{ // binary fusion transformation template <typename SignatureT> struct result; template <typename Q> struct result<from_value(double const&, Q const&)>{ typedef Q type; }; template<typename Q> Q operator()(double const& value, Q const&) const{ return Q::from_value(value); } };
I had to use the *binary* version of transform because the type of the result depends on the destination fusion::vector.
The other way around from vector<quantity<T1> ... quantity<TN> > to array<double, N> should be easier (because the destination type is always double by using the quantity<T>::value() ) but I didn't managed because I didn't find the way to convert from vector<double*N> to array<double, N>. ideas?
Thank you for making fusion, it is an incredible library once you realize what it is for. Alfredo
You do know that based on this:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adapted/boo... boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?
yes, thank you, that what I wrote in my last post . I can make this work #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> ... boost::array<double, 3> boostarr={{1.0, 2.1, 3.2}}; vector<double, double, double> fusionvec(boostarr); //now works I still can't do the other way around: boost::array<double, 3> boostarr2(fusionvec); //doesn't work ideas? _______________________________________________
Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe Boost Users beigetreten sind. Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an boostusers@googlegroups.com. Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an boostusers+unsubscribe@googlegroups.com<boostusers%2Bunsubscribe@googlegroups.com> . Besuchen Sie die Gruppe unter http://groups.google.com/group/boostusers?hl=de, um weitere Optionen zu erhalten.

On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.correa@gmail.com> wrote:
On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
You do know that based on this:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adapted/boo... boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?
yes, thank you, that what I wrote in my last post . I can make this work
#include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> ... boost::array<double, 3> boostarr={{1.0, 2.1, 3.2}}; vector<double, double, double> fusionvec(boostarr); //now works
Ah, heh, got lost in the noise and I missed it. On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.correa@gmail.com> wrote:
I still can't do the other way around:
boost::array<double, 3> boostarr2(fusionvec); //doesn't work ideas?
I know that would not work because that is still a 'custom' type as far as fusion is concerned, and only free functions can work on it, a constructor is obviously not a free function, so you need to write a free function to do it (probably called 'copy', probably using fusion's foreach to copy each element one to the other, should be pretty well optimized out thanks to the template-magic).

On Oct 7, 5:13 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.cor...@gmail.com> wrote:
On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1 <overmind...@gmail.com> wrote:
You do know that based on this:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adap... boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?
yes, thank you, that what I wrote in my last post . I can make this work
#include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> ... boost::array<double, 3> boostarr={{1.0, 2.1, 3.2}}; vector<double, double, double> fusionvec(boostarr); //now works
Ah, heh, got lost in the noise and I missed it.
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.cor...@gmail.com> wrote:
I still can't do the other way around:
boost::array<double, 3> boostarr2(fusionvec); //doesn't work ideas?
I know that would not work because that is still a 'custom' type as far as fusion is concerned, and only free functions can work on it, a constructor is obviously not a free function, so you need to write a free function to do it (probably called 'copy', probably using fusion's foreach to copy each element one to the other, should be pretty well optimized out thanks to the template-magic).
no luck. I can't make it work. First I tried with "for_each" and didn't manage to put together the code because I need to copy one sequence from the other and the for_each doesn't keep track of the index. So I tried with "transform", the code compiles but does nothing to the array. boost::array<double, 3> ba0; boost::fusion::transform(ba0, bfv1, copy()); where struct copy{ typedef void result_type; void operator()(double& lhs, double const& rhs) const{ lhs = rhs; } }; ba0 is still undefined after running this. Obviously I am getting Boost.Fusion wrong. Thanks, Alfredo
_______________________________________________ Boost-users mailing list Boost-us...@lists.boost.orghttp://lists.boost.org/mailman/listinfo.cgi/boost-users

alfC wrote:
On Oct 7, 5:13 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.cor...@gmail.com> wrote:
On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1 <overmind...@gmail.com> wrote:
You do know that based on this:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adap...
boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?
yes, thank you, that what I wrote in my last post . I can make this work
#include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> ... boost::array<double, 3> boostarr={{1.0, 2.1, 3.2}}; vector<double, double, double> fusionvec(boostarr); //now works
Ah, heh, got lost in the noise and I missed it.
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <alfredo.cor...@gmail.com> wrote:
I still can't do the other way around:
boost::array<double, 3> boostarr2(fusionvec); //doesn't work ideas?
I know that would not work because that is still a 'custom' type as far as fusion is concerned, and only free functions can work on it, a constructor is obviously not a free function, so you need to write a free function to do it (probably called 'copy', probably using fusion's foreach to copy each element one to the other, should be pretty well optimized out thanks to the template-magic).
no luck. I can't make it work. First I tried with "for_each" and didn't manage to put together the code because I need to copy one sequence from the other and the for_each doesn't keep track of the index. So I tried with "transform", the code compiles but does nothing to the array.
boost::array<double, 3> ba0; boost::fusion::transform(ba0, bfv1, copy());
where struct copy{ typedef void result_type; void operator()(double& lhs, double const& rhs) const{ lhs = rhs; } };
ba0 is still undefined after running this.
Obviously I am getting Boost.Fusion wrong.
Thanks, Alfredo
You will find a version using fold attached. What it does, is that it increases the size of the boost::array passed in as state by one for every element in the fusion sequence and copies over the elements. There could be a more elegant solution to the problem ;) Cheers

2010/10/8 Thomas Heller <thom.heller@googlemail.com>
alfC wrote:
On Oct 7, 5:13 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa <
alfredo.cor...@gmail.com>
wrote:
On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1 <overmind...@gmail.com> wrote:
You do know that based on this:
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/adap...
boost::array is already adapted as a fusion container and can be used directly, as soon as you include the proper hpp that is?
yes, thank you, that what I wrote in my last post . I can make this work
#include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> ... boost::array<double, 3> boostarr={{1.0, 2.1, 3.2}}; vector<double, double, double> fusionvec(boostarr); //now works
Ah, heh, got lost in the noise and I missed it.
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa < alfredo.cor...@gmail.com> wrote:
I still can't do the other way around:
boost::array<double, 3> boostarr2(fusionvec); //doesn't work ideas?
I know that would not work because that is still a 'custom' type as far as fusion is concerned, and only free functions can work on it, a constructor is obviously not a free function, so you need to write a free function to do it (probably called 'copy', probably using fusion's foreach to copy each element one to the other, should be pretty well optimized out thanks to the template-magic).
no luck. I can't make it work. First I tried with "for_each" and didn't manage to put together the code because I need to copy one sequence from the other and the for_each doesn't keep track of the index. So I tried with "transform", the code compiles but does nothing to the array.
boost::array<double, 3> ba0; boost::fusion::transform(ba0, bfv1, copy());
where struct copy{ typedef void result_type; void operator()(double& lhs, double const& rhs) const{ lhs = rhs; } };
ba0 is still undefined after running this.
Obviously I am getting Boost.Fusion wrong.
Thanks, Alfredo
You will find a version using fold attached. What it does, is that it increases the size of the boost::array passed in as state by one for every element in the fusion sequence and copies over the elements. There could be a more elegant solution to the problem ;)
Thomas, thanks so much for the code. Unfortunately it doesn't work (maybe it is my compiler?) $ c++ -v gcc 4.4.3 $ c++ fusion_test.cpp $ ./a.out terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::out_of_range>
' what(): attempt to access element of an empty array Aborted
Thanks, Alfredo
Cheers
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users -- Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe Boost Users beigetreten sind. Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an boostusers@googlegroups.com. Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an boostusers+unsubscribe@googlegroups.com<boostusers%2Bunsubscribe@googlegroups.com> . Besuchen Sie die Gruppe unter http://groups.google.com/group/boostusers?hl=de, um weitere Optionen zu erhalten.

On Oct 6, 5:33 pm, Joel de Guzman <j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ... >? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple. Fusion, which is supposed to be an extension of boost::tuple (or at least that was my understanding), lost such feature that I could exploit. The situation is the following: quantity<U,T> because it claims that has no runtime cost, this is like saying that it can be interpreted as its underlying type T (e.g. double). All numerical routines that I am using take fixed arrays of double or basically boost::arrays. The analogy is perfect if I use tuples because I can reinterpret them as arrays back *and* forth without copying anything or adding any additional code. Since I can't do this with fusion::vector then I will have to use boost::tuples. This will be a pain in it self because then I will have to manually code MPL to tuples generation and loose the nice fusion::transforms. It seem I am out of luck, and just fallen in a crack between tuples and fusion. There is second possibility that is that I got the boost::fusion theory totally wrong in the first place. Thanks so much for your help, Alfredo.
Regards, -- Joel de Guzmanhttp://www.boostpro.comhttp://spirit.sf.net
_______________________________________________ Boost-users mailing list Boost-us...@lists.boost.orghttp://lists.boost.org/mailman/listinfo.cgi/boost-users

On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure). Disregarding any of that is playing with fire. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman <joel@boost-consulting.com> wrote:
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure).
Disregarding any of that is playing with fire.
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy): // Proper includes here... struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); } }; typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType; arrType arr(1,1,1); vecType vec(5,5,5); for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5)); Nice and simple; there might be a better way, but these kind of things suit me perfectly, and who knows, there might be a Phoenix way to do set1stTo2nd instead of the functor.

On Oct 8, 8:00 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
<j...@boost-consulting.com> wrote:
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure).
Disregarding any of that is playing with fire.
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
// Proper includes here...
struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); }};
typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
arrType arr(1,1,1); vecType vec(5,5,5);
for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5));
Thank you very much for the code. Unfortunately it doesn't work, compiles but it doesn't copy the vector into the array. Below is the full program, it leaves the array intact. It doesn't make sense either, the for_each argument has only two elements, the array and the vector. The for_each will just first "do" the array and then "do" the vector, but it just seems to assign the first element of each to the second but not copying values from the vector to the array. (I still remember the time when I could copy one an array of doubles to the other.) Below is the full program if you want to give it a try: #include<boost/array.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include<iostream> using std::clog; using std::endl; using namespace boost::fusion; struct set1stTo2nd { template<typename T> void operator()(T& t) const { deref(boost::fusion::begin(t)) = deref(boost::fusion::next(boost::fusion::begin(t))); } }; typedef boost::array<double,3> arrType; typedef boost::fusion::vector<double,double,double> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType; int main(){ boost::array<double, 3> arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl; boost::fusion::vector<double, double, double> vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl; boost::array<double, 3> arr2; for_each(zipSeqType(arr2,vec1), set1stTo2nd()); clog << "arr2: " << at_c<0>(arr2) << ", "<< at_c<1>(arr2) << ", " << at_c<2>(arr2) << endl; return 0; } prints: arr1: 1, 2.1, 3.2 vec1: 1, 2.1, 3.2 arr2: 4.85589e-270, 4.85589e-270, 4.90963e-270

Am 09.10.2010 11:24, schrieb alfC:
On Oct 8, 8:00 pm, OvermindDL1 <overmind...@gmail.com> wrote:
[snip]
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
// Proper includes here...
struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); }};
typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
arrType arr(1,1,1); vecType vec(5,5,5);
for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5));
Thank you very much for the code. Unfortunately it doesn't work, compiles but it doesn't copy the vector into the array. Below is the full program, it leaves the array intact.
It doesn't make sense either, the for_each argument has only two elements, the array and the vector. The for_each will just first "do" the array and then "do" the vector, but it just seems to assign the first element of each to the second but not copying values from the vector to the array.
(I still remember the time when I could copy one an array of doubles to the other.) Below is the full program if you want to give it a try:
#include<boost/array.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include<iostream> using std::clog; using std::endl;
using namespace boost::fusion; struct set1stTo2nd { template<typename T> void operator()(T& t) const { deref(boost::fusion::begin(t)) = deref(boost::fusion::next(boost::fusion::begin(t))); } };
typedef boost::array<double,3> arrType; typedef boost::fusion::vector<double,double,double> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
int main(){ boost::array<double, 3> arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl;
boost::fusion::vector<double, double, double> vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl;
boost::array<double, 3> arr2; for_each(zipSeqType(arr2,vec1), set1stTo2nd());
fusion::zip(arr2,vec1) should be used here, or fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)) . http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/t... http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/view/zip_vi...
clog << "arr2: " << at_c<0>(arr2) << ", "<< at_c<1>(arr2) << ", " << at_c<2>(arr2) << endl; return 0; }
prints: arr1: 1, 2.1, 3.2 vec1: 1, 2.1, 3.2 arr2: 4.85589e-270, 4.85589e-270, 4.90963e-270
-Christopher

On Oct 9, 2:24 am, alfC <alfredo.cor...@gmail.com> wrote:
On Oct 8, 8:00 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
<j...@boost-consulting.com> wrote:
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
Hi,
I am trying to convert a boost::array into a fusion::vector. reinterpreting the memory from boost::array. It works for tuples but not fusion::vector, why is that. Is there a way to make it work? ( I was hoping that the memory layout is the same to make conversion from one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure).
Disregarding any of that is playing with fire.
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
// Proper includes here...
struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); }};
typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
arrType arr(1,1,1); vecType vec(5,5,5);
for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5));
FINALLY! I got it. I feel better now. It turns out that the correct line of code is for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() ); you wrote the correct typedef but then didn't apply the zip_view function. (Although, related to the original question, I am still a bit worried about too much unnecessary copy which seems unavoidable since the memory layout of array<double, N> and fusion::vector<double*N> is different.) below is the full program that *works*: #include<boost/array.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include <boost/fusion/algorithm/transformation/zip.hpp> #include <boost/fusion/include/zip.hpp> #include <boost/fusion/view/zip_view.hpp> #include <boost/fusion/include/zip_view.hpp> #include<iostream> using std::clog; using std::endl; using namespace boost::fusion; struct set1stTo2nd { template<typename T> void operator()(T t) const { deref(boost::fusion::begin(t)) = deref(boost::fusion::next(boost::fusion::begin(t))); } }; typedef boost::array<double,3> arrType; typedef boost::fusion::vector<double,double,double> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType; int main(){ boost::array<double, 3> arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl; boost::fusion::vector<double, double, double> vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl; boost::array<double, 3> arr2; for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() ); clog << "arr2: " << at_c<0>(arr2) << ", "<< at_c<1>(arr2) << ", " << at_c<2>(arr2) << endl; return 0; } prints: arr1: 1, 2.1, 3.2 vec1: 1, 2.1, 3.2 arr2: 1, 2.1, 3.2 Have a good weekend, Alfredo

On 10/9/2010 6:11 PM, alfC wrote:
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
Yep. We need fusion to have two algorithms: copy and copy_if. Any takers? Should be easy. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

AMDG On 10/9/2010 7:42 AM, Joel de Guzman wrote:
On 10/9/2010 6:11 PM, alfC wrote:
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
Yep. We need fusion to have two algorithms: copy and copy_if. Any takers? Should be easy.
I have an implementation of copy somewhere, if I can find it. In Christ, Steven Watanabe

On 10/10/2010 12:00 AM, Steven Watanabe wrote:
AMDG
On 10/9/2010 7:42 AM, Joel de Guzman wrote:
On 10/9/2010 6:11 PM, alfC wrote:
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
Yep. We need fusion to have two algorithms: copy and copy_if. Any takers? Should be easy.
I have an implementation of copy somewhere, if I can find it.
Cool. I'd appreciate that, Steven. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On Oct 9, 2010, at 12:00 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
On 10/9/2010 7:42 AM, Joel de Guzman wrote:
Yep. We need fusion to have two algorithms: copy and copy_if. Any takers? Should be easy.
I have an implementation of copy somewhere, if I can find it.
Hence, copy...if. ;-)

On Sat, Oct 9, 2010 at 4:11 AM, alfC <alfredo.correa@gmail.com> wrote:
On Oct 9, 2:24 am, alfC <alfredo.cor...@gmail.com> wrote:
On Oct 8, 8:00 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
<j...@boost-consulting.com> wrote:
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
On 10/7/2010 3:53 AM, alfC wrote:
> Hi,
> I am trying to convert a boost::array into a fusion::vector. > reinterpreting the memory from boost::array. It works for tuples but > not fusion::vector, why is that. Is there a way to make it work? ( I > was hoping that the memory layout is the same to make conversion from > one to the other very easy.)
Don't do that. It will *never* be guaranteed to work even if it works now. The memory layout of fusion::vector is an internal implementation detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure).
Disregarding any of that is playing with fire.
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
// Proper includes here...
struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); }};
typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
arrType arr(1,1,1); vecType vec(5,5,5);
for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5));
FINALLY! I got it. I feel better now.
It turns out that the correct line of code is
for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() );
you wrote the correct typedef but then didn't apply the zip_view function.
(Although, related to the original question, I am still a bit worried about too much unnecessary copy which seems unavoidable since the memory layout of array<double, N> and fusion::vector<double*N> is different.)
below is the full program that *works*:
#include<boost/array.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include <boost/fusion/algorithm/transformation/zip.hpp> #include <boost/fusion/include/zip.hpp> #include <boost/fusion/view/zip_view.hpp> #include <boost/fusion/include/zip_view.hpp>
#include<iostream> using std::clog; using std::endl;
using namespace boost::fusion; struct set1stTo2nd { template<typename T> void operator()(T t) const { deref(boost::fusion::begin(t)) = deref(boost::fusion::next(boost::fusion::begin(t))); } };
typedef boost::array<double,3> arrType; typedef boost::fusion::vector<double,double,double> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
int main(){ boost::array<double, 3> arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl;
boost::fusion::vector<double, double, double> vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl;
boost::array<double, 3> arr2; for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() ); clog << "arr2: " << at_c<0>(arr2) << ", "<< at_c<1>(arr2) << ", " << at_c<2>(arr2) << endl; return 0; }
prints: arr1: 1, 2.1, 3.2 vec1: 1, 2.1, 3.2 arr2: 1, 2.1, 3.2
Have a good weekend, Alfredo
Yeah, my mistake, busy at work and not paying attention, I meant to have the fusion::zip there. :)

On Sat, Oct 9, 2010 at 7:53 AM, OvermindDL1 <overminddl1@gmail.com> wrote:
On Sat, Oct 9, 2010 at 4:11 AM, alfC <alfredo.correa@gmail.com> wrote:
On Oct 9, 2:24 am, alfC <alfredo.cor...@gmail.com> wrote:
On Oct 8, 8:00 pm, OvermindDL1 <overmind...@gmail.com> wrote:
On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
<j...@boost-consulting.com> wrote:
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman<j...@boost-consulting.com> wrote:
> On 10/7/2010 3:53 AM, alfC wrote:
>> Hi,
>> I am trying to convert a boost::array into a fusion::vector. >> reinterpreting the memory from boost::array. It works for tuples but >> not fusion::vector, why is that. Is there a way to make it work? ( I >> was hoping that the memory layout is the same to make conversion from >> one to the other very easy.)
> Don't do that. It will *never* be guaranteed to work even if it works > now. The memory layout of fusion::vector is an internal implementation > detail and can change anytime.
The question is: is it guaranteed for boost::tuples<double, double, ...>? (it seems so, just by the PODness of tuples of PODs in its stated design.) If so, then it is a *feature* of boost::tuple.
No it is not. 1) It is not documented 2) It is not a POD 3) Anything with a reinterpret_cast is not guaranteed to work (you can only rely on reinterpret_cast only when casting back from a lost type e.g. through type erasure).
Disregarding any of that is playing with fire.
The previous posts a few posts ago seems overly complicated, I would just do this (suitably wrapped into a function to handle it, maybe named copy):
// Proper includes here...
struct set1stTo2nd { template<typename T> void operator()(T& t) const { using namespace boost::fusion; deref(begin(t)) = deref(next(begin(t))); }};
typedef boost::array<int,3> arrType; typedef boost::fusion::vector<int,int,int> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
arrType arr(1,1,1); vecType vec(5,5,5);
for_each(zipSeqType(arr,vec), set1stTo2nd()); assert(arr == make_vector(5,5,5));
FINALLY! I got it. I feel better now.
It turns out that the correct line of code is
for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() );
you wrote the correct typedef but then didn't apply the zip_view function.
(Although, related to the original question, I am still a bit worried about too much unnecessary copy which seems unavoidable since the memory layout of array<double, N> and fusion::vector<double*N> is different.)
below is the full program that *works*:
#include<boost/array.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/include/container.hpp> #include <boost/fusion/adapted/boost_array.hpp> #include <boost/fusion/include/boost_array.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include <boost/fusion/algorithm/transformation/zip.hpp> #include <boost/fusion/include/zip.hpp> #include <boost/fusion/view/zip_view.hpp> #include <boost/fusion/include/zip_view.hpp>
#include<iostream> using std::clog; using std::endl;
using namespace boost::fusion; struct set1stTo2nd { template<typename T> void operator()(T t) const { deref(boost::fusion::begin(t)) = deref(boost::fusion::next(boost::fusion::begin(t))); } };
typedef boost::array<double,3> arrType; typedef boost::fusion::vector<double,double,double> vecType; typedef boost::fusion::vector<arrType&,vecType&> zipSeqType;
int main(){ boost::array<double, 3> arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl;
boost::fusion::vector<double, double, double> vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl;
boost::array<double, 3> arr2; for_each( boost::fusion::zip_view<zipSeqType>(zipSeqType(arr2,vec1)), set1stTo2nd() ); clog << "arr2: " << at_c<0>(arr2) << ", "<< at_c<1>(arr2) << ", " << at_c<2>(arr2) << endl; return 0; }
prints: arr1: 1, 2.1, 3.2 vec1: 1, 2.1, 3.2 arr2: 1, 2.1, 3.2
Have a good weekend, Alfredo
Yeah, my mistake, busy at work and not paying attention, I meant to have the fusion::zip there. :)
another subtlety is that the correct signature is struct set1stTo2nd { template<typename T> void operator()(T t) const // not T& t) const ...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe Boost Users beigetreten sind. Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an boostusers@googlegroups.com. Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an boostusers+unsubscribe@googlegroups.com. Besuchen Sie die Gruppe unter http://groups.google.com/group/boostusers?hl=de, um weitere Optionen zu erhalten.
participants (9)
-
alfC
-
Alfredo Correa
-
Alfredo Correa
-
Christopher Schmidt
-
Joel de Guzman
-
Nat Goodspeed
-
OvermindDL1
-
Steven Watanabe
-
Thomas Heller