[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
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
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
On Wed, Oct 6, 2010 at 10:54 PM, alfC
On Oct 6, 5:33 pm, Joel de Guzman
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
to vector : I found the feature of the library that allows conversion from array to vector . Just by including #include #include boost::array
ba={{1.0, 2.1, 3.2}}; vector bfv1(ba); //works. I still can the other way around. boost::array
ba0(bfv1); //doesn't work ideas? great, I also managed to solve the original problem on how to convert from boost::array
to fusion::vector 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
si::length, quantitysi::time, quantitysi::mass > vector_of_q; vector_of_q fvq( transform( ba, // boost::array // 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
{ 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
to array 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 to array . 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
On Wed, Oct 6, 2010 at 10:54 PM, alfC
wrote: On Oct 6, 5:33 pm, Joel de Guzman
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
to vector : I found the feature of the library that allows conversion from array to vector . Just by including #include #include boost::array
ba={{1.0, 2.1, 3.2}}; vector bfv1(ba); //works. I still can the other way around. boost::array
ba0(bfv1); //doesn't work ideas? great, I also managed to solve the original problem on how to convert from boost::array
to fusion::vector 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
si::length, quantitysi::time, quantitysi::mass > vector_of_q; vector_of_q fvq( transform( ba, // boost::array // 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
{ 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
to array 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 to array . 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-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.
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa
On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1
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
#include ... boost::array boostarr={{1.0, 2.1, 3.2}}; vector 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
I still can't do the other way around:
boost::array
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
On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa
wrote: On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1
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
#include ... boost::array boostarr={{1.0, 2.1, 3.2}}; vector 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
wrote: I still can't do the other way around:
boost::array
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
_______________________________________________ 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
wrote: On Thu, Oct 7, 2010 at 5:42 PM, Alfredo Correa
wrote: On Thu, Oct 7, 2010 at 3:33 PM, OvermindDL1
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
#include ... boost::array boostarr={{1.0, 2.1, 3.2}}; vector 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
wrote: I still can't do the other way around:
boost::array
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
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
alfC wrote:
On Oct 7, 5:13 pm, OvermindDL1
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
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
#include ... boost::array boostarr={{1.0, 2.1, 3.2}}; vector 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
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
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
' 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
. 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
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
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
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
? (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
On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman
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
? (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
On Oct 8, 8:00 pm, OvermindDL1
On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
wrote: On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman
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
? (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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector 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
Am 09.10.2010 11:24, schrieb alfC:
On Oct 8, 8:00 pm, OvermindDL1
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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector 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
#include #include #include #include #include #include #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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector zipSeqType; int main(){ boost::array
arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl; boost::fusion::vector
vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl; boost::array
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
On Oct 8, 8:00 pm, OvermindDL1
wrote: On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
wrote: On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman
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
? (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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector 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
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
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
On Oct 9, 2:24 am, alfC
wrote: On Oct 8, 8:00 pm, OvermindDL1
wrote: On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
wrote: On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman
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
? (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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector 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
and fusion::vector is different.) below is the full program that *works*:
#include
#include #include #include #include #include #include #include #include #include #include #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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector zipSeqType; int main(){ boost::array
arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl; boost::fusion::vector
vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl; boost::array
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
On Sat, Oct 9, 2010 at 4:11 AM, alfC
wrote: On Oct 9, 2:24 am, alfC
wrote: On Oct 8, 8:00 pm, OvermindDL1
wrote: On Fri, Oct 8, 2010 at 6:57 PM, Joel de Guzman
wrote: On 10/9/2010 2:44 AM, alfC wrote:
On Oct 6, 5:33 pm, Joel de Guzman
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
? (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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector 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
and fusion::vector is different.) below is the full program that *works*:
#include
#include #include #include #include #include #include #include #include #include #include #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
arrType; typedef boost::fusion::vector vecType; typedef boost::fusion::vector zipSeqType; int main(){ boost::array
arr1={{1.0, 2.1, 3.2}}; clog << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl; boost::fusion::vector
vec1(arr1); clog << "vec1: " << at_c<0>(vec1) << ", "<< at_c<1>(vec1) << ", " << at_c<2>(vec1) << endl; boost::array
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