
Neil Groves wrote:
Thank you ever so much for taking the time to implement your suggestion. I will make sure I review this code sometime this week. I'm sure that if there are no breaking changes and no gotchas that we can get this into the trunk soon.
Thanks for your response, Neil. [Some gotchas in the implementation]: * C++11 features (rvalue references and decltype) are used. * When applying range adaptors in `moved_range`, a moved container is evaluated as **const lvalue reference**. (This is because the implementation uses `boost::fusion::accumulate` to apply range adaptors.) * The pipe operator of an rvalue `moved_range` has higher priority than the pipe operators for all other range adaptors (e.g. `reverse_forwarder`) in overload resolution: template <typename Adaptor> moved_range<Container, typename meta::push_back<Adaptors, Adaptor>::type> operator|(moved_range<Container, Adaptors>&& rng, Adaptor const& adpt); template<typename Range> reversed_range<Range> operator|(Range& rng, reverse_forwarder); So, when adding rvalue overloading to range adaptors in the future, we need to avoid ambiguity on overload resolution for the pipe operator. Suppose we are adding rvalue overloading for `reverse_forwarder`: template<typename Range> reversed_range<Range> operator|(Range&& rng, reverse_forwarder); This results in compiler errors due to ambiguity. To avoid ambiguity, we need to lower its priority in overload resolution: template<typename Range, typename Adaptor> typename boost::enable_if< boost::is_same<Adaptor, reverse_forwarder> , reversed_range<Range> >::type operator|(Range&& rng, Adaptor); Or just SFINAE out `moved_range`: template<typename Range> typename boost::disable_if< is_moved_range<Range> , reversed_range<Range> >::type operator|(Range&& rng, reverse_forwarder); [Not yet implemented in the current implementation]: * #ifndef'ing the code using `BOOST_NO_RVALUE_REFERENCES` and `BOOST_NO_DECLTYPE`. * Don't return `moved_range`, if the input to the pipe operator of `moved_forwarder` is `iterator_range`. * Built-in array support. * Add specialization for `moved_range<Range, boost::fusion::vector<> >` to reduce its space overhead. Regards, Michel