Boost logo

Boost Users :

Subject: Re: [Boost-users] [fusion] memory layout of fusion::vector vs boost::tuple/boost::array
From: alfC (alfredo.correa_at_[hidden])
Date: 2010-10-09 05:24:22


On Oct 8, 8:00 pm, OvermindDL1 <overmind..._at_[hidden]> wrote:
> On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
>
>
>
> <j..._at_[hidden]> wrote:
> > On 10/9/2010 2:44 AM, alfC wrote:
>
> >> On Oct 6, 5:33 pm, Joel de Guzman<j..._at_[hidden]>  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


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