blob: 42eb52a2c7ee4458aa8e3893334228f6884f6521 [file] [log] [blame]
Brian Silverman598d0292018-08-04 23:56:47 -07001// 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
25namespace 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, class Value >
105 inline replaced_range<SinglePassRange>
106 operator|(SinglePassRange& r, const replace_holder<Value>& f)
107 {
108 BOOST_RANGE_CONCEPT_ASSERT((
109 SinglePassRangeConcept<SinglePassRange>));
110
111 return replaced_range<SinglePassRange>(r, f.val1, f.val2);
112 }
113
114 template< class SinglePassRange, class Value >
115 inline replaced_range<const SinglePassRange>
116 operator|(const SinglePassRange& r, const replace_holder<Value>& f)
117 {
118 BOOST_RANGE_CONCEPT_ASSERT((
119 SinglePassRangeConcept<const SinglePassRange>));
120
121 return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
122 }
123 } // 'range_detail'
124
125 using range_detail::replaced_range;
126
127 namespace adaptors
128 {
129 namespace
130 {
131 const range_detail::forwarder2<range_detail::replace_holder>
132 replaced =
133 range_detail::forwarder2<range_detail::replace_holder>();
134 }
135
136 template< class SinglePassRange, class Value >
137 inline replaced_range<SinglePassRange>
138 replace(SinglePassRange& rng, Value from, Value to)
139 {
140 BOOST_RANGE_CONCEPT_ASSERT((
141 SinglePassRangeConcept<SinglePassRange>));
142
143 return replaced_range<SinglePassRange>(rng, from, to);
144 }
145
146 template< class SinglePassRange, class Value >
147 inline replaced_range<const SinglePassRange>
148 replace(const SinglePassRange& rng, Value from, Value to)
149 {
150 BOOST_RANGE_CONCEPT_ASSERT((
151 SinglePassRangeConcept<const SinglePassRange>));
152
153 return replaced_range<const SinglePassRange>(rng, from ,to);
154 }
155
156 } // 'adaptors'
157} // 'boost'
158
159#endif // include guard