File indexing completed on 2025-01-18 09:51:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
0012 #define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
0013
0014 #include <boost/config.hpp>
0015 #include <boost/range/adaptor/argument_fwd.hpp>
0016 #include <boost/range/iterator_range.hpp>
0017 #include <boost/range/begin.hpp>
0018 #include <boost/range/end.hpp>
0019 #include <boost/range/value_type.hpp>
0020 #include <boost/range/concepts.hpp>
0021 #include <boost/iterator/iterator_adaptor.hpp>
0022 #include <boost/iterator/transform_iterator.hpp>
0023 #include <boost/optional/optional.hpp>
0024
0025 namespace boost
0026 {
0027 namespace range_detail
0028 {
0029 template< class Value >
0030 class replace_value
0031 {
0032 public:
0033 typedef const Value& result_type;
0034 typedef const Value& first_argument_type;
0035
0036
0037
0038
0039 replace_value()
0040 {
0041 }
0042
0043 replace_value(const Value& from, const Value& to)
0044 : m_impl(data(from, to))
0045 {
0046 }
0047
0048 const Value& operator()(const Value& x) const
0049 {
0050 return (x == m_impl->m_from) ? m_impl->m_to : x;
0051 }
0052
0053 private:
0054 struct data
0055 {
0056 data(const Value& from, const Value& to)
0057 : m_from(from)
0058 , m_to(to)
0059 {
0060 }
0061
0062 Value m_from;
0063 Value m_to;
0064 };
0065 boost::optional<data> m_impl;
0066 };
0067
0068 template< class R >
0069 class replaced_range :
0070 public boost::iterator_range<
0071 boost::transform_iterator<
0072 replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
0073 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
0074 {
0075 private:
0076 typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
0077
0078 typedef boost::iterator_range<
0079 boost::transform_iterator<
0080 replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
0081 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
0082
0083 public:
0084 typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
0085
0086 replaced_range( R& r, value_type from, value_type to )
0087 : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
0088 make_transform_iterator( boost::end(r), Fn(from, to) ) )
0089 { }
0090 };
0091
0092 template< class T >
0093 class replace_holder : public holder2<T>
0094 {
0095 public:
0096 replace_holder( const T& from, const T& to )
0097 : holder2<T>(from, to)
0098 { }
0099 private:
0100
0101 void operator=(const replace_holder&);
0102 };
0103
0104 template< class SinglePassRange, class Value >
0105 inline replaced_range<SinglePassRange>
0106 operator|(SinglePassRange& r, const replace_holder<Value>& f)
0107 {
0108 BOOST_RANGE_CONCEPT_ASSERT((
0109 SinglePassRangeConcept<SinglePassRange>));
0110
0111 return replaced_range<SinglePassRange>(r, f.val1, f.val2);
0112 }
0113
0114 template< class SinglePassRange, class Value >
0115 inline replaced_range<const SinglePassRange>
0116 operator|(const SinglePassRange& r, const replace_holder<Value>& f)
0117 {
0118 BOOST_RANGE_CONCEPT_ASSERT((
0119 SinglePassRangeConcept<const SinglePassRange>));
0120
0121 return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
0122 }
0123 }
0124
0125 using range_detail::replaced_range;
0126
0127 namespace adaptors
0128 {
0129 namespace
0130 {
0131 const range_detail::forwarder2<range_detail::replace_holder>
0132 replaced =
0133 range_detail::forwarder2<range_detail::replace_holder>();
0134 }
0135
0136 template< class SinglePassRange, class Value >
0137 inline replaced_range<SinglePassRange>
0138 replace(SinglePassRange& rng, Value from, Value to)
0139 {
0140 BOOST_RANGE_CONCEPT_ASSERT((
0141 SinglePassRangeConcept<SinglePassRange>));
0142
0143 return replaced_range<SinglePassRange>(rng, from, to);
0144 }
0145
0146 template< class SinglePassRange, class Value >
0147 inline replaced_range<const SinglePassRange>
0148 replace(const SinglePassRange& rng, Value from, Value to)
0149 {
0150 BOOST_RANGE_CONCEPT_ASSERT((
0151 SinglePassRangeConcept<const SinglePassRange>));
0152
0153 return replaced_range<const SinglePassRange>(rng, from ,to);
0154 }
0155
0156 }
0157 }
0158
0159 #endif