16
16
#include < boost/range/iterator_range.hpp>
17
17
#include < boost/range/begin.hpp>
18
18
#include < boost/range/end.hpp>
19
- #include < boost/range/value_type .hpp>
19
+ #include < boost/range/reference .hpp>
20
20
#include < boost/range/concepts.hpp>
21
21
#include < boost/iterator/iterator_adaptor.hpp>
22
22
#include < boost/iterator/transform_iterator.hpp>
23
23
#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/remove_const.hpp>
27
+ #include < boost/type_traits/is_reference.hpp>
28
+ #include < boost/type_traits/conditional.hpp>
24
29
25
30
namespace boost
26
31
{
27
32
namespace range_detail
28
33
{
29
- template < class Pred , class Value >
34
+ template < class Pred , class Reference >
30
35
class replace_value_if
31
36
{
32
37
public:
33
- typedef const Value& result_type;
34
- typedef const Value& first_argument_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;
35
42
36
43
// Rationale:
37
44
// required to allow the iterator to be default constructible.
38
45
replace_value_if ()
39
46
{
40
47
}
41
48
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)
43
50
: m_impl(data(pred, to))
44
51
{
45
52
}
46
53
47
- const Value& operator ()(const Value& x) const
54
+ result_type operator ()(Reference x) const
48
55
{
56
+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
49
57
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
50
61
}
51
62
52
63
private:
64
+
65
+
53
66
struct data
54
67
{
55
- data (const Pred& p, const Value & t)
68
+ data (const Pred& p, const BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type & t)
56
69
: m_pred(p), m_to(t)
57
70
{
58
71
}
59
72
60
73
Pred m_pred;
61
- Value m_to;
74
+ BOOST_DEDUCED_TYPENAME boost::remove_const<BOOST_DEDUCED_TYPENAME boost::remove_reference<Reference>::type>::type m_to;
62
75
};
63
76
boost::optional<data> m_impl;
64
77
};
@@ -67,21 +80,21 @@ namespace boost
67
80
class replaced_if_range :
68
81
public boost::iterator_range<
69
82
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 >,
71
84
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
72
85
{
73
86
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;
75
88
76
89
typedef boost::iterator_range<
77
90
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 >,
79
92
BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t ;
80
93
81
94
public:
82
- typedef BOOST_DEDUCED_TYPENAME range_value <R>::type value_type ;
95
+ typedef BOOST_DEDUCED_TYPENAME range_reference <R>::type reference_type ;
83
96
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 )
85
98
: base_t ( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
86
99
make_transform_iterator ( boost::end(r), Fn(pred, to) ) )
87
100
{ }
0 commit comments