[fusion] iterating over a sequence with non-const references

Hi,
I would like to iterate over a sequence and preserve the
reference/const/non-const of the elements. That is say I have
a sequence like this:
tuple

on Sat Mar 31 2012, paul Fultz
Hi, I would like to iterate over a sequence and preserve the
reference/const/non-const of the elements. That is say I have a sequence like this:
tuple
seq; I would like to this to be true:
typeof(deref(begin(seq))) == int& typeof(deref(next(begin(seq)))) == int&&
It seems fusion sequences always return a const reference to the element. Is there a workaround to get it to work like this?
Trust me, you don't want that, for roughly the same reason you don't want regular sequence rvalues to have rvalue-returning iterators: https://groups.google.com/d/msg/comp.lang.c++.moderated/1BwNTHCFiOs/L1T3WC9T...
Or is this just not possible with Boost.Fusion?
I think you'd need to create your own iterator fusion-style iterator for this purpose.
Furthermore, I would like to use the transformation algorithms (especially push_back, and push_front) and still preserve the reference type.
Sorry, I don't know what that means. How could using an algorithm change a sequence's (or iterator's?) reference type?
Is that possible, through some workarounds? Finally, would it still be fairly efficient when dealing with references, to copy the tuple and make a new tuple when doing algorithms such as push_back or push_front? Or is the lazy evaluation much more efficient than that?
This part is best answered by others. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hi, I would like to iterate over a sequence and preserve the
reference/const/non-const of the elements. That is say I have a sequence like this:
tuple
seq; I would like to this to be true:
typeof(deref(begin(seq))) == int& typeof(deref(next(begin(seq)))) == int&&
It seems fusion sequences always return a const reference to the element. Is there a workaround to get it to work like this?
Trust me, you don't want that, for roughly the same reason you don't want regular sequence rvalues to have rvalue-returning iterators: https://groups.google.com/d/msg/comp.lang.c++.moderated/1BwNTHCFiOs/L1T3WC9T...
I can see how that would be bad. Im using it to invoke functions which wouldn't be a problem for that, but other use cases would cause problems. Right now, it won't return a non-const reference from the iterator for tuples.
Or is this just not possible with Boost.Fusion?
I think you'd need to create your own iterator fusion-style iterator for this purpose.
Furthermore, I would like to use the transformation algorithms (especially push_back, and push_front) and still preserve the reference type.
Sorry, I don't know what that means. How could using an algorithm change a sequence's (or iterator's?) reference type?
Well for example in push_back, it adds const to the sequence like this:
result_of::push_back

On 4/2/2012 3:56 AM, paul Fultz wrote:
Hi, I would like to iterate over a sequence and preserve the
reference/const/non-const of the elements. That is say I have a sequence like this:
tuple
seq; I would like to this to be true:
typeof(deref(begin(seq))) == int& typeof(deref(next(begin(seq)))) == int&&
It seems fusion sequences always return a const reference to the element. Is there a workaround to get it to work like this?
Trust me, you don't want that, for roughly the same reason you don't want regular sequence rvalues to have rvalue-returning iterators: https://groups.google.com/d/msg/comp.lang.c++.moderated/1BwNTHCFiOs/L1T3WC9T...
I can see how that would be bad. Im using it to invoke functions which wouldn't be a problem for that, but other use cases would cause problems. Right now, it won't return a non-const reference from the iterator for tuples.
Or is this just not possible with Boost.Fusion?
I think you'd need to create your own iterator fusion-style iterator for this purpose.
Furthermore, I would like to use the transformation algorithms (especially push_back, and push_front) and still preserve the reference type.
Sorry, I don't know what that means. How could using an algorithm change a sequence's (or iterator's?) reference type?
Well for example in push_back, it adds const to the sequence like this:
result_of::push_back
Which will cause all references in the sequence to become const, as well.
Thanks, for the reply, but im thinking about just implementing an invoke that works just for tuples, but multiple tuples can be given. That way I won't need to use push_back and push_front. I will just need to find a way to bring together all the tuples before the invoke.
push_back is designed to be non-mutating. That is why. This is true of all the views returned from 'algos', by design. What you can do is to make a container from the view through, e.g. as_vector, as_list. It is *not* true that all sequences return const refs to its elements. Containers definitely return references, otherwise get<N>(c)= expr will not be possible. (That being said, I'm considering allowing mutable views) Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

push_back is designed to be non-mutating. That is why. This is true of all the views returned from 'algos', by design. What you can do is to make a container from the view through, e.g. as_vector, as_list. It is *not* true that all sequences return const refs to its elements. Containers definitely return references, otherwise get<N>(c)= expr will not be possible.
Also, front and back return non-const reference, but thats not the point.
During iteration, they return const reference. Thats why this is not
possible:
struct mutable_func
{
template<class F>
struct result;
template

On 4/3/2012 2:45 AM, paul Fultz wrote:
push_back is designed to be non-mutating. That is why. This is true of all the views returned from 'algos', by design. What you can do is to make a container from the view through, e.g. as_vector, as_list. It is *not* true that all sequences return const refs to its elements. Containers definitely return references, otherwise get<N>(c)= expr will not be possible.
Also, front and back return non-const reference, but thats not the point. During iteration, they return const reference. Thats why this is not possible:
struct mutable_func { template<class F> struct result;
template
struct result { typedef T type; }; template
T operator()(T && x, U y) const { return x+=y; } }; int i = 0; invoke(foo, tuple
(i, 1)); //doesn't compile here is the output:
What is 'foo'? Anyway, this (below) compiles fine with me with
g++ 4.6.1 and MSVC 10:
#include

----- Original Message -----
From: Joel de Guzman
To: boost-users@lists.boost.org Cc: Sent: Monday, April 2, 2012 11:26 PM Subject: Re: [Boost-users] [fusion] iterating over a sequence with non-const references On 4/3/2012 2:45 AM, paul Fultz wrote:
push_back is designed to be non-mutating. That is why. This is true of all the views returned from 'algos', by design. What you can do is to make a container from the view through, e.g. as_vector, as_list. It is *not* true that all sequences return const refs to its elements. Containers definitely return references, otherwise get<N>(c)= expr will not be possible.
Also, front and back return non-const reference, but thats not the point. During iteration, they return const reference. Thats why this is not possible:
struct mutable_func { template<class F> struct result;
template
struct result { typedef T type; }; template
T operator()(T && x, U y) const { return x+=y; } }; int i = 0; invoke(foo, tuple
(i, 1)); //doesn't compile here is the output:
What is 'foo'? mutable_func foo = {}; I forgot that line.
Anyway, this (below) compiles fine with me with g++ 4.6.1 and MSVC 10:
Yea, sorry about that. It seems it was still calling my own invoke and there
was a mistake in that. If you call invoke like this:
std::cout << invoke(mutable_func(), forward_as_tuple(i, 1)) << std::endl;
There are two errors:
invoke.hpp:209:24: error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'
return f( BOOST_PP_ENUM(N,M,~) );
^~~~~~~~~~~~~~~~~~~~~~~~~
Which I assume is because invoke takes the sequence as a const-reference
because it is a temporary. But then why does the other example work(its also
a temporary)?
The second error is:
at_impl.hpp:45:28: error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'
return std::get

On 4/3/2012 10:50 PM, paul Fultz wrote:
Yea, sorry about that. It seems it was still calling my own invoke and there was a mistake in that. If you call invoke like this:
std::cout << invoke(mutable_func(), forward_as_tuple(i, 1)) << std::endl;
There are two errors:
invoke.hpp:209:24: error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int' return f( BOOST_PP_ENUM(N,M,~) ); ^~~~~~~~~~~~~~~~~~~~~~~~~
Which I assume is because invoke takes the sequence as a const-reference because it is a temporary. But then why does the other example work(its also a temporary)?
The int& held in the tuple will always be mutable regardless if the holder tuple is const, that is why it works. I don't know what else you are doing with forward_as_tuple. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

The int& held in the tuple will always be mutable regardless if the holder tuple is const, that is why it works. I don't know what else you are doing with forward_as_tuple.
But I thought since this overload is provided for get:
template< std::size_t I, class... Types >
typename std::tuple_element >::type const&
get( const tuple

On 4/4/2012 11:42 AM, paul Fultz wrote:
The int& held in the tuple will always be mutable regardless if the holder tuple is const, that is why it works. I don't know what else you are doing with forward_as_tuple.
But I thought since this overload is provided for get:
template< std::size_t I, class... Types >
typename std::tuple_element >::type const&
get( const tuple
& t ); Then it would add const to the reference. Also, forward_as_tuple is just the std::forward_as_tuple.
Nope. That is not correct. See:
#include
participants (3)
-
Dave Abrahams
-
Joel de Guzman
-
paul Fultz