Imported Upstream version 1.57.0
[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/range/concepts.hpp>
21 #include <boost/iterator/iterator_adaptor.hpp>
22 #include <boost/iterator/transform_iterator.hpp>
23 #include <boost/optional/optional.hpp>
24
25 namespace boost
26 {
27     namespace range_detail
28     {
29         template< class Value >
30         class replace_value
31         {
32         public:
33             typedef const Value& result_type;
34             typedef const Value& first_argument_type;
35
36             // Rationale:
37             // The default constructor is required to allow the transform
38             // iterator to properly model the iterator concept.
39             replace_value()
40             {
41             }
42
43             replace_value(const Value& from, const Value& to)
44                 :   m_impl(data(from, to))
45             {
46             }
47
48             const Value& operator()(const Value& x) const
49             {
50                 return (x == m_impl->m_from) ? m_impl->m_to : x;
51             }
52
53         private:
54             struct data
55             {
56                 data(const Value& from, const Value& to)
57                     : m_from(from)
58                     , m_to(to)
59                 {
60                 }
61
62                 Value m_from;
63                 Value m_to;
64             };
65             boost::optional<data> m_impl;
66         };
67
68         template< class R >
69         class replaced_range :
70             public boost::iterator_range<
71                 boost::transform_iterator<
72                     replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
73                     BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
74         {
75         private:
76             typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
77
78             typedef boost::iterator_range<
79                 boost::transform_iterator<
80                     replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
81                     BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
82
83         public:
84             typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
85
86             replaced_range( R& r, value_type from, value_type to )
87                 : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
88                           make_transform_iterator( boost::end(r), Fn(from, to) ) )
89             { }
90         };
91
92         template< class T >
93         class replace_holder : public holder2<T>
94         {
95         public:
96             replace_holder( const T& from, const T& to )
97                 : holder2<T>(from, to)
98             { }
99         private:
100             // not assignable
101             void operator=(const replace_holder&);
102         };
103
104         template< class SinglePassRange >
105         inline replaced_range<SinglePassRange>
106         operator|(
107             SinglePassRange& r,
108             const replace_holder<
109                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f )
110         {
111             BOOST_RANGE_CONCEPT_ASSERT((
112                 SinglePassRangeConcept<SinglePassRange>));
113
114             return replaced_range<SinglePassRange>(r, f.val1, f.val2);
115         }
116
117         template< class SinglePassRange >
118         inline replaced_range<const SinglePassRange>
119         operator|(
120             const SinglePassRange& r,
121             const replace_holder<
122                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
123         {
124             BOOST_RANGE_CONCEPT_ASSERT((
125                 SinglePassRangeConcept<const SinglePassRange>));
126
127             return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
128         }
129     } // 'range_detail'
130
131     using range_detail::replaced_range;
132
133     namespace adaptors
134     {
135         namespace
136         {
137             const range_detail::forwarder2<range_detail::replace_holder>
138                 replaced =
139                     range_detail::forwarder2<range_detail::replace_holder>();
140         }
141
142         template<class SinglePassRange>
143         inline replaced_range<SinglePassRange>
144         replace(SinglePassRange& rng,
145                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
146                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
147         {
148             BOOST_RANGE_CONCEPT_ASSERT((
149                 SinglePassRangeConcept<SinglePassRange>));
150
151             return replaced_range<SinglePassRange>(rng, from, to);
152         }
153
154         template<class SinglePassRange>
155         inline replaced_range<const SinglePassRange>
156         replace(const SinglePassRange& rng,
157                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
158                 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
159         {
160             BOOST_RANGE_CONCEPT_ASSERT((
161                 SinglePassRangeConcept<const SinglePassRange>));
162
163             return replaced_range<const SinglePassRange>(rng, from ,to);
164         }
165
166     } // 'adaptors'
167 } // 'boost'
168
169 #endif // include guard