Chris@16
|
1 // Boost.Range library
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright Neil Groves 2007. Use, modification and
|
Chris@16
|
4 // distribution is subject to the Boost Software License, Version
|
Chris@16
|
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 // For more information, see http://www.boost.org/libs/range/
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
|
Chris@16
|
12 #define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/config.hpp>
|
Chris@16
|
15 #include <boost/range/adaptor/argument_fwd.hpp>
|
Chris@16
|
16 #include <boost/range/iterator_range.hpp>
|
Chris@16
|
17 #include <boost/range/begin.hpp>
|
Chris@16
|
18 #include <boost/range/end.hpp>
|
Chris@16
|
19 #include <boost/range/value_type.hpp>
|
Chris@101
|
20 #include <boost/range/concepts.hpp>
|
Chris@16
|
21 #include <boost/iterator/iterator_adaptor.hpp>
|
Chris@16
|
22 #include <boost/iterator/transform_iterator.hpp>
|
Chris@101
|
23 #include <boost/optional/optional.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 namespace boost
|
Chris@16
|
26 {
|
Chris@16
|
27 namespace range_detail
|
Chris@16
|
28 {
|
Chris@16
|
29 template< class Value >
|
Chris@16
|
30 class replace_value
|
Chris@16
|
31 {
|
Chris@16
|
32 public:
|
Chris@16
|
33 typedef const Value& result_type;
|
Chris@16
|
34 typedef const Value& first_argument_type;
|
Chris@16
|
35
|
Chris@101
|
36 // Rationale:
|
Chris@101
|
37 // The default constructor is required to allow the transform
|
Chris@101
|
38 // iterator to properly model the iterator concept.
|
Chris@101
|
39 replace_value()
|
Chris@101
|
40 {
|
Chris@101
|
41 }
|
Chris@101
|
42
|
Chris@16
|
43 replace_value(const Value& from, const Value& to)
|
Chris@101
|
44 : m_impl(data(from, to))
|
Chris@16
|
45 {
|
Chris@16
|
46 }
|
Chris@16
|
47
|
Chris@16
|
48 const Value& operator()(const Value& x) const
|
Chris@16
|
49 {
|
Chris@101
|
50 return (x == m_impl->m_from) ? m_impl->m_to : x;
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 private:
|
Chris@101
|
54 struct data
|
Chris@101
|
55 {
|
Chris@101
|
56 data(const Value& from, const Value& to)
|
Chris@101
|
57 : m_from(from)
|
Chris@101
|
58 , m_to(to)
|
Chris@101
|
59 {
|
Chris@101
|
60 }
|
Chris@101
|
61
|
Chris@101
|
62 Value m_from;
|
Chris@101
|
63 Value m_to;
|
Chris@101
|
64 };
|
Chris@101
|
65 boost::optional<data> m_impl;
|
Chris@16
|
66 };
|
Chris@16
|
67
|
Chris@16
|
68 template< class R >
|
Chris@16
|
69 class replaced_range :
|
Chris@16
|
70 public boost::iterator_range<
|
Chris@16
|
71 boost::transform_iterator<
|
Chris@16
|
72 replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
Chris@16
|
73 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
|
Chris@16
|
74 {
|
Chris@16
|
75 private:
|
Chris@16
|
76 typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
|
Chris@16
|
77
|
Chris@16
|
78 typedef boost::iterator_range<
|
Chris@16
|
79 boost::transform_iterator<
|
Chris@16
|
80 replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
|
Chris@16
|
81 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
|
Chris@16
|
82
|
Chris@16
|
83 public:
|
Chris@16
|
84 typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
|
Chris@16
|
85
|
Chris@16
|
86 replaced_range( R& r, value_type from, value_type to )
|
Chris@16
|
87 : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
|
Chris@16
|
88 make_transform_iterator( boost::end(r), Fn(from, to) ) )
|
Chris@16
|
89 { }
|
Chris@16
|
90 };
|
Chris@16
|
91
|
Chris@16
|
92 template< class T >
|
Chris@16
|
93 class replace_holder : public holder2<T>
|
Chris@16
|
94 {
|
Chris@16
|
95 public:
|
Chris@16
|
96 replace_holder( const T& from, const T& to )
|
Chris@16
|
97 : holder2<T>(from, to)
|
Chris@16
|
98 { }
|
Chris@16
|
99 private:
|
Chris@16
|
100 // not assignable
|
Chris@16
|
101 void operator=(const replace_holder&);
|
Chris@16
|
102 };
|
Chris@16
|
103
|
Chris@101
|
104 template< class SinglePassRange >
|
Chris@101
|
105 inline replaced_range<SinglePassRange>
|
Chris@101
|
106 operator|(
|
Chris@101
|
107 SinglePassRange& r,
|
Chris@101
|
108 const replace_holder<
|
Chris@101
|
109 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f )
|
Chris@16
|
110 {
|
Chris@101
|
111 BOOST_RANGE_CONCEPT_ASSERT((
|
Chris@101
|
112 SinglePassRangeConcept<SinglePassRange>));
|
Chris@101
|
113
|
Chris@101
|
114 return replaced_range<SinglePassRange>(r, f.val1, f.val2);
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@101
|
117 template< class SinglePassRange >
|
Chris@101
|
118 inline replaced_range<const SinglePassRange>
|
Chris@101
|
119 operator|(
|
Chris@101
|
120 const SinglePassRange& r,
|
Chris@101
|
121 const replace_holder<
|
Chris@101
|
122 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
|
Chris@16
|
123 {
|
Chris@101
|
124 BOOST_RANGE_CONCEPT_ASSERT((
|
Chris@101
|
125 SinglePassRangeConcept<const SinglePassRange>));
|
Chris@101
|
126
|
Chris@101
|
127 return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
|
Chris@16
|
128 }
|
Chris@16
|
129 } // 'range_detail'
|
Chris@16
|
130
|
Chris@16
|
131 using range_detail::replaced_range;
|
Chris@16
|
132
|
Chris@16
|
133 namespace adaptors
|
Chris@16
|
134 {
|
Chris@16
|
135 namespace
|
Chris@16
|
136 {
|
Chris@16
|
137 const range_detail::forwarder2<range_detail::replace_holder>
|
Chris@16
|
138 replaced =
|
Chris@16
|
139 range_detail::forwarder2<range_detail::replace_holder>();
|
Chris@16
|
140 }
|
Chris@16
|
141
|
Chris@101
|
142 template<class SinglePassRange>
|
Chris@101
|
143 inline replaced_range<SinglePassRange>
|
Chris@101
|
144 replace(SinglePassRange& rng,
|
Chris@101
|
145 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
|
Chris@101
|
146 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
|
Chris@16
|
147 {
|
Chris@101
|
148 BOOST_RANGE_CONCEPT_ASSERT((
|
Chris@101
|
149 SinglePassRangeConcept<SinglePassRange>));
|
Chris@101
|
150
|
Chris@101
|
151 return replaced_range<SinglePassRange>(rng, from, to);
|
Chris@16
|
152 }
|
Chris@16
|
153
|
Chris@101
|
154 template<class SinglePassRange>
|
Chris@101
|
155 inline replaced_range<const SinglePassRange>
|
Chris@101
|
156 replace(const SinglePassRange& rng,
|
Chris@101
|
157 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
|
Chris@101
|
158 BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
|
Chris@16
|
159 {
|
Chris@101
|
160 BOOST_RANGE_CONCEPT_ASSERT((
|
Chris@101
|
161 SinglePassRangeConcept<const SinglePassRange>));
|
Chris@101
|
162
|
Chris@101
|
163 return replaced_range<const SinglePassRange>(rng, from ,to);
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 } // 'adaptors'
|
Chris@16
|
167 } // 'boost'
|
Chris@16
|
168
|
Chris@16
|
169 #endif // include guard
|