deeb8da072410d55bd80bcc8e47d3f5e1562b32f
[platform/upstream/boost.git] / boost / range / adaptor / replaced.hpp
1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2007. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10
11 #ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
12 #define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
13
14 #include <boost/config.hpp>
15 #include <boost/range/adaptor/argument_fwd.hpp>
16 #include <boost/range/iterator_range.hpp>
17 #include <boost/range/begin.hpp>
18 #include <boost/range/end.hpp>
19 #include <boost/range/value_type.hpp>
20 #include <boost/iterator/iterator_adaptor.hpp>
21 #include <boost/iterator/transform_iterator.hpp>
22
23 namespace boost
24 {
25     namespace range_detail
26     {
27         template< class Value >
28         class replace_value
29         {
30         public:
31             typedef const Value& result_type;
32             typedef const Value& first_argument_type;
33
34             replace_value(const Value& from, const Value& to)
35                 :   m_from(from), m_to(to)
36             {
37             }
38
39             const Value& operator()(const Value& x) const
40             {
41                 return (x == m_from) ? m_to : x;
42             }
43
44         private:
45             Value m_from;
46             Value m_to;
47         };
48
49         template< class R >
50         class replaced_range :
51             public boost::iterator_range<
52                 boost::transform_iterator<
53                     replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
54                     BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
55         {
56         private:
57             typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
58
59             typedef boost::iterator_range<
60                 boost::transform_iterator<
61                     replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
62                     BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
63
64         public:
65             typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
66
67             replaced_range( R& r, value_type from, value_type to )
68                 : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
69                           make_transform_iterator( boost::end(r), Fn(from, to) ) )
70             { }
71         };
72
73         template< class T >
74         class replace_holder : public holder2<T>
75         {
76         public:
77             replace_holder( const T& from, const T& to )
78                 : holder2<T>(from, to)
79             { }
80         private:
81             // not assignable
82             void operator=(const replace_holder&);
83         };
84
85         template< class InputRng >
86         inline replaced_range<InputRng>
87         operator|( InputRng& r,
88                    const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
89         {
90             return replaced_range<InputRng>(r, f.val1, f.val2);
91         }
92
93         template< class InputRng >
94         inline replaced_range<const InputRng>
95         operator|( const InputRng& r,
96                    const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
97         {
98             return replaced_range<const InputRng>(r, f.val1, f.val2);
99         }
100     } // 'range_detail'
101
102     using range_detail::replaced_range;
103
104     namespace adaptors
105     {
106         namespace
107         {
108             const range_detail::forwarder2<range_detail::replace_holder>
109                 replaced =
110                     range_detail::forwarder2<range_detail::replace_holder>();
111         }
112
113         template<class InputRange>
114         inline replaced_range<InputRange>
115         replace(InputRange& rng,
116                 BOOST_DEDUCED_TYPENAME range_value<InputRange>::type from,
117                 BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
118         {
119             return replaced_range<InputRange>(rng, from, to);
120         }
121
122         template<class InputRange>
123         inline replaced_range<const InputRange>
124         replace(const InputRange& rng,
125                 BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type from,
126                 BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
127         {
128             return replaced_range<const InputRange>(rng, from ,to);
129         }
130
131     } // 'adaptors'
132 } // 'boost'
133
134 #endif // include guard