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::conditionalboost::is_referenceReference result_type;
38+ typedef BOOST_DEDUCED_TYPENAME boost::conditional<boost::is_reference<Reference>::value,
39+ const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type&,
40+ Reference>::type result_type;
41+ typedef Reference first_argument_type;
3542
3643 // Rationale:
3744 // required to allow the iterator to be default constructible.
3845 replace_value_if ()
3946 {
4047 }
4148
42- replace_value_if (const Pred& pred, const Value & to)
49+ replace_value_if (const Pred& pred, const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type & to)
4350 : m_impl(data(pred, to))
4451 {
4552 }
4653
47- const Value& operator ()(const Value& x) const
54+ result_type operator ()(Reference x) const
4855 {
56+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4957 return m_impl->m_pred (x) ? m_impl->m_to : x;
58+ #else
59+ return m_impl->m_pred (x) ? m_impl->m_to : boost::forward<Reference>(x);
60+ #endif
5061 }
5162
5263 private:
64+
65+
5366 struct data
5467 {
55- data (const Pred& p, const Value & t)
68+ data (const Pred& p, const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type & t)
5669 : m_pred(p), m_to(t)
5770 {
5871 }
5972
6073 Pred m_pred;
61- Value m_to;
74+ BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type m_to;
6275 };
6376 boost::optional<data> m_impl;
6477 };
@@ -67,21 +80,21 @@ namespace boost
6780 class replaced_if_range :
6881 public boost::iterator_range<
6982 boost::transform_iterator<
70- replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type >,
83+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type >,
7184 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
7285 {
7386 private:
74- typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type > Fn;
87+ typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type > Fn;
7588
7689 typedef boost::iterator_range<
7790 boost::transform_iterator<
78- replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value <R>::type >,
91+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_reference <R>::type >,
7992 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t ;
8093
8194 public:
82- typedef BOOST_DEDUCED_TYPENAME range_value <R>::type value_type ;
95+ typedef BOOST_DEDUCED_TYPENAME range_reference <R>::type reference_type ;
8396
84- replaced_if_range ( R& r, const Pred& pred, value_type to )
97+ replaced_if_range ( R& r, const Pred& pred, const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference_type>::type& to )
8598 : base_t ( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
8699 make_transform_iterator ( boost::end(r), Fn(pred, to) ) )
87100 { }
0 commit comments