Chris@16: // Boost.Range library Chris@16: // Chris@16: // Copyright Neil Groves 2007. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/range/ Chris@16: // Chris@16: Chris@16: #ifndef BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED Chris@16: #define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace range_detail Chris@16: { Chris@16: template< class Pred, class Value > Chris@16: class replace_value_if Chris@16: { Chris@16: public: Chris@16: typedef const Value& result_type; Chris@16: typedef const Value& first_argument_type; Chris@16: Chris@101: // Rationale: Chris@101: // required to allow the iterator to be default constructible. Chris@101: replace_value_if() Chris@101: { Chris@101: } Chris@101: Chris@16: replace_value_if(const Pred& pred, const Value& to) Chris@101: : m_impl(data(pred, to)) Chris@16: { Chris@16: } Chris@16: Chris@16: const Value& operator()(const Value& x) const Chris@16: { Chris@101: return m_impl->m_pred(x) ? m_impl->m_to : x; Chris@16: } Chris@16: Chris@16: private: Chris@101: struct data Chris@101: { Chris@101: data(const Pred& p, const Value& t) Chris@101: : m_pred(p), m_to(t) Chris@101: { Chris@101: } Chris@101: Chris@101: Pred m_pred; Chris@101: Value m_to; Chris@101: }; Chris@101: boost::optional m_impl; Chris@16: }; Chris@16: Chris@16: template< class Pred, class R > Chris@16: class replaced_if_range : Chris@16: public boost::iterator_range< Chris@16: boost::transform_iterator< Chris@16: replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type >, Chris@16: BOOST_DEDUCED_TYPENAME range_iterator::type > > Chris@16: { Chris@16: private: Chris@16: typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type > Fn; Chris@16: Chris@16: typedef boost::iterator_range< Chris@16: boost::transform_iterator< Chris@16: replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value::type >, Chris@16: BOOST_DEDUCED_TYPENAME range_iterator::type > > base_t; Chris@16: Chris@16: public: Chris@16: typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; Chris@16: Chris@16: replaced_if_range( R& r, const Pred& pred, value_type to ) Chris@16: : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ), Chris@16: make_transform_iterator( boost::end(r), Fn(pred, to) ) ) Chris@16: { } Chris@16: }; Chris@16: Chris@16: template< class Pred, class T > Chris@16: class replace_if_holder Chris@16: { Chris@16: public: Chris@16: replace_if_holder( const Pred& pred, const T& to ) Chris@16: : m_pred(pred), m_to(to) Chris@16: { } Chris@16: Chris@16: const Pred& pred() const { return m_pred; } Chris@16: const T& to() const { return m_to; } Chris@16: Chris@16: private: Chris@16: Pred m_pred; Chris@16: T m_to; Chris@16: }; Chris@16: Chris@101: template< class Pred, class SinglePassRange > Chris@101: inline replaced_if_range Chris@101: operator|( Chris@101: SinglePassRange& r, Chris@101: const replace_if_holder< Chris@101: Pred, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type>& f) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_if_range( Chris@101: r, f.pred(), f.to()); Chris@16: } Chris@16: Chris@101: template< class Pred, class SinglePassRange > Chris@101: inline replaced_if_range Chris@101: operator|( Chris@101: const SinglePassRange& r, Chris@101: const replace_if_holder< Chris@101: Pred, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type>& f) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_if_range( Chris@101: r, f.pred(), f.to()); Chris@16: } Chris@16: } // 'range_detail' Chris@16: Chris@16: using range_detail::replaced_if_range; Chris@16: Chris@16: namespace adaptors Chris@16: { Chris@16: namespace Chris@16: { Chris@16: const range_detail::forwarder2TU Chris@16: replaced_if = Chris@16: range_detail::forwarder2TU(); Chris@16: } Chris@101: Chris@101: template Chris@101: inline replaced_if_range Chris@101: replace_if(SinglePassRange& rng, Pred pred, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type to) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return range_detail::replaced_if_range( Chris@101: rng, pred, to); Chris@16: } Chris@16: Chris@101: template Chris@101: inline replaced_if_range Chris@101: replace_if( Chris@101: const SinglePassRange& rng, Chris@101: Pred pred, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type to) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return range_detail::replaced_if_range( Chris@101: rng, pred, to); Chris@16: } Chris@16: } // 'adaptors' Chris@101: Chris@16: } // 'boost' Chris@16: Chris@16: #endif // include guard