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_IF_IMPL_HPP_INCLUDED
0012 #define BOOST_RANGE_ADAPTOR_REPLACED_IF_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 Pred, class Value >
0030 class replace_value_if
0031 {
0032 public:
0033 typedef const Value& result_type;
0034 typedef const Value& first_argument_type;
0035
0036
0037
0038 replace_value_if()
0039 {
0040 }
0041
0042 replace_value_if(const Pred& pred, const Value& to)
0043 : m_impl(data(pred, to))
0044 {
0045 }
0046
0047 const Value& operator()(const Value& x) const
0048 {
0049 return m_impl->m_pred(x) ? m_impl->m_to : x;
0050 }
0051
0052 private:
0053 struct data
0054 {
0055 data(const Pred& p, const Value& t)
0056 : m_pred(p), m_to(t)
0057 {
0058 }
0059
0060 Pred m_pred;
0061 Value m_to;
0062 };
0063 boost::optional<data> m_impl;
0064 };
0065
0066 template< class Pred, class R >
0067 class replaced_if_range :
0068 public boost::iterator_range<
0069 boost::transform_iterator<
0070 replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
0071 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
0072 {
0073 private:
0074 typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
0075
0076 typedef boost::iterator_range<
0077 boost::transform_iterator<
0078 replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
0079 BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
0080
0081 public:
0082 typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
0083
0084 replaced_if_range( R& r, const Pred& pred, value_type to )
0085 : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
0086 make_transform_iterator( boost::end(r), Fn(pred, to) ) )
0087 { }
0088 };
0089
0090 template< class Pred, class T >
0091 class replace_if_holder
0092 {
0093 public:
0094 replace_if_holder( const Pred& pred, const T& to )
0095 : m_pred(pred), m_to(to)
0096 { }
0097
0098 const Pred& pred() const { return m_pred; }
0099 const T& to() const { return m_to; }
0100
0101 private:
0102 Pred m_pred;
0103 T m_to;
0104 };
0105
0106 template< class Pred, class SinglePassRange, class Value >
0107 inline replaced_if_range<Pred, SinglePassRange>
0108 operator|(SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
0109 {
0110 BOOST_RANGE_CONCEPT_ASSERT((
0111 SinglePassRangeConcept<SinglePassRange>));
0112
0113 return replaced_if_range<Pred, SinglePassRange>(
0114 r, f.pred(), f.to());
0115 }
0116
0117 template< class Pred, class SinglePassRange, class Value >
0118 inline replaced_if_range<Pred, const SinglePassRange>
0119 operator|(const SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
0120 {
0121 BOOST_RANGE_CONCEPT_ASSERT((
0122 SinglePassRangeConcept<const SinglePassRange>));
0123
0124 return replaced_if_range<Pred, const SinglePassRange>(
0125 r, f.pred(), f.to());
0126 }
0127 }
0128
0129 using range_detail::replaced_if_range;
0130
0131 namespace adaptors
0132 {
0133 namespace
0134 {
0135 const range_detail::forwarder2TU<range_detail::replace_if_holder>
0136 replaced_if =
0137 range_detail::forwarder2TU<range_detail::replace_if_holder>();
0138 }
0139
0140 template< class Pred, class SinglePassRange, class Value >
0141 inline replaced_if_range<Pred, SinglePassRange>
0142 replace_if(SinglePassRange& rng, Pred pred, Value to)
0143 {
0144 BOOST_RANGE_CONCEPT_ASSERT((
0145 SinglePassRangeConcept<SinglePassRange>));
0146
0147 return range_detail::replaced_if_range<Pred, SinglePassRange>(
0148 rng, pred, to);
0149 }
0150
0151 template< class Pred, class SinglePassRange, class Value >
0152 inline replaced_if_range<Pred, const SinglePassRange>
0153 replace_if(const SinglePassRange& rng, Pred pred, Value to)
0154 {
0155 BOOST_RANGE_CONCEPT_ASSERT((
0156 SinglePassRangeConcept<const SinglePassRange>));
0157
0158 return range_detail::replaced_if_range<Pred, const SinglePassRange>(
0159 rng, pred, to);
0160 }
0161 }
0162
0163 }
0164
0165 #endif