1616#include < boost/range/iterator_range.hpp>
1717#include < boost/range/begin.hpp>
1818#include < boost/range/end.hpp>
19- #include < boost/range/value_type .hpp>
19+ #include < boost/range/reference .hpp>
2020#include < boost/range/concepts.hpp>
2121#include < boost/iterator/iterator_adaptor.hpp>
2222#include < boost/iterator/transform_iterator.hpp>
2323#include < boost/optional/optional.hpp>
24+ #include < boost/move/utility_core.hpp>
25+ #include < boost/type_traits/remove_reference.hpp>
26+ #include < boost/type_traits/is_reference.hpp>
27+ #include < boost/type_traits/conditional.hpp>
2428
2529namespace boost
2630{
2731 namespace range_detail
2832 {
29- template < class Pred , class Value >
33+ template < class Pred , class Reference >
3034 class replace_value_if
3135 {
3236 public:
33- typedef const Value& result_type;
34- typedef const Value& first_argument_type;
37+ typedef BOOST_DEDUCED_TYPENAME boost::conditional<boost::is_reference<Reference>::value,
38+ const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type&,
39+ Reference>::type result_type;
40+ typedef Reference first_argument_type;
3541
3642 // Rationale:
3743 // required to allow the iterator to be default constructible.
3844 replace_value_if ()
3945 {
4046 }
4147
42- replace_value_if (const Pred& pred, const Value & to)
48+ replace_value_if (const Pred& pred, const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type & to)
4349 : m_impl(data(pred, to))
4450 {
4551 }
4652
47- const Value& operator ()(const Value& x) const
53+ result_type operator ()(Reference x) const
4854 {
55+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4956 return m_impl->m_pred (x) ? m_impl->m_to : x;
57+ #else
58+ return m_impl->m_pred (x) ? m_impl->m_to : boost::forward<Reference>(x);
59+ #endif
5060 }
5161
5262 private:
63+
64+
5365 struct data
5466 {
55- data (const Pred& p, const Value & t)
67+ data (const Pred& p, const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type & t)
5668 : m_pred(p), m_to(t)
5769 {
5870 }
5971
6072 Pred m_pred;
61- Value m_to;
73+ BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type m_to;
6274 };
6375 boost::optional<data> m_impl;
6476 };
@@ -67,21 +79,21 @@ namespace boost
6779 class replaced_if_range :
6880 public boost::iterator_range<
6981 boost::transform_iterator<
70- replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type >,
82+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type >,
7183 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
7284 {
7385 private:
74- typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type > Fn;
86+ typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type > Fn;
7587
7688 typedef boost::iterator_range<
7789 boost::transform_iterator<
78- replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type >,
90+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type >,
7991 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t ;
8092
8193 public:
82- typedef BOOST_DEDUCED_TYPENAME range_value <R>::type value_type ;
94+ typedef BOOST_DEDUCED_TYPENAME range_reference <R>::type reference_type ;
8395
84- replaced_if_range ( R& r, const Pred& pred, value_type to )
96+ replaced_if_range ( R& r, const Pred& pred, const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference_type>::type& to )
8597 : base_t ( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
8698 make_transform_iterator ( boost::end(r), Fn(pred, to) ) )
8799 { }
0 commit comments