|
Boost : |
Subject: Re: [boost] [Range] Range adaptor approach for temporary range lifetime issue
From: Michel Morin (mimomorin_at_[hidden])
Date: 2012-06-18 06:05:50
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk